]> git.saurik.com Git - apple/objc4.git/blob - runtime/Messengers.subproj/objc-msg-simulator-i386.s
objc4-818.2.tar.gz
[apple/objc4.git] / runtime / Messengers.subproj / objc-msg-simulator-i386.s
1 /*
2 * Copyright (c) 1999-2009 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #include <TargetConditionals.h>
25 #if defined(__i386__) && TARGET_OS_SIMULATOR
26
27 #include "objc-config.h"
28
29 .data
30
31 // _objc_restartableRanges is used by method dispatch
32 // to get the critical regions for which method caches
33 // cannot be garbage collected.
34
35 .macro RestartableEntry
36 .long $0
37 .long 0
38 .short LExit$0 - $0
39 .short 0xffff // The simulator doesn't support kernel based recovery
40 .long 0
41 .endmacro
42
43 .align 4
44 .private_extern _objc_restartableRanges
45 _objc_restartableRanges:
46 RestartableEntry _cache_getImp
47 RestartableEntry _objc_msgSend
48 RestartableEntry _objc_msgSend_fpret
49 RestartableEntry _objc_msgSend_stret
50 RestartableEntry _objc_msgSendSuper
51 RestartableEntry _objc_msgSendSuper2
52 RestartableEntry _objc_msgSendSuper_stret
53 RestartableEntry _objc_msgSendSuper2_stret
54 RestartableEntry _objc_msgLookup
55 RestartableEntry _objc_msgLookup_fpret
56 RestartableEntry _objc_msgLookup_stret
57 RestartableEntry _objc_msgLookupSuper2
58 RestartableEntry _objc_msgLookupSuper2_stret
59 .fill 16, 1, 0
60
61
62 /********************************************************************
63 * Names for relative labels
64 * DO NOT USE THESE LABELS ELSEWHERE
65 * Reserved labels: 5: 6: 7: 8: 9:
66 ********************************************************************/
67 #define LCacheMiss 5
68 #define LCacheMiss_f 5f
69 #define LCacheMiss_b 5b
70 #define LNilTestDone 6
71 #define LNilTestDone_f 6f
72 #define LNilTestDone_b 6b
73 #define LNilTestSlow 7
74 #define LNilTestSlow_f 7f
75 #define LNilTestSlow_b 7b
76 #define LGetIsaDone 8
77 #define LGetIsaDone_f 8f
78 #define LGetIsaDone_b 8b
79 #define LGetIsaSlow 9
80 #define LGetIsaSlow_f 9f
81 #define LGetIsaSlow_b 9b
82
83 /********************************************************************
84 * Macro parameters
85 ********************************************************************/
86
87
88 #define NORMAL 0
89 #define FPRET 1
90 #define STRET 2
91
92 #define CALL 100
93 #define GETIMP 101
94 #define LOOKUP 102
95
96
97 /********************************************************************
98 *
99 * Structure definitions.
100 *
101 ********************************************************************/
102
103 // Offsets from %esp
104 #define self 4
105 #define super 4
106 #define selector 8
107 #define marg_size 12
108 #define marg_list 16
109 #define first_arg 12
110
111 #define struct_addr 4
112
113 #define self_stret 8
114 #define super_stret 8
115 #define selector_stret 12
116 #define marg_size_stret 16
117 #define marg_list_stret 20
118
119 // objc_super parameter to sendSuper
120 #define receiver 0
121 #define class 4
122
123 // Selected field offsets in class structure
124 #define isa 0
125 #define superclass 4
126 #define cache_buckets 8
127 #define cache_mask 12
128
129 // Method cache
130 #define cached_sel 0
131 #define cached_imp 4
132
133 // Method descriptor
134 #define method_name 0
135 #define method_imp 8
136
137
138 //////////////////////////////////////////////////////////////////////
139 //
140 // ENTRY functionName
141 //
142 // Assembly directives to begin an exported function.
143 //
144 // Takes: functionName - name of the exported function
145 //////////////////////////////////////////////////////////////////////
146
147 .macro ENTRY
148 .text
149 .globl $0
150 .align 2, 0x90
151 $0:
152 .endmacro
153
154 .macro STATIC_ENTRY
155 .text
156 .private_extern $0
157 .align 4, 0x90
158 $0:
159 .endmacro
160
161 //////////////////////////////////////////////////////////////////////
162 //
163 // END_ENTRY functionName
164 //
165 // Assembly directives to end an exported function. Just a placeholder,
166 // a close-parenthesis for ENTRY, until it is needed for something.
167 //
168 // Takes: functionName - name of the exported function
169 //////////////////////////////////////////////////////////////////////
170
171 .macro END_ENTRY
172 LExit$0:
173 .endmacro
174
175
176 /********************************************************************
177 * UNWIND name, flags
178 * Unwind info generation
179 ********************************************************************/
180 .macro UNWIND
181 .section __LD,__compact_unwind,regular,debug
182 .long $0
183 .set LUnwind$0, LExit$0 - $0
184 .long LUnwind$0
185 .long $1
186 .long 0 /* no personality */
187 .long 0 /* no LSDA */
188 .text
189 .endmacro
190
191 #define NoFrame 0x02010000 // no frame, no SP adjustment except return address
192 #define FrameWithNoSaves 0x01000000 // frame, no non-volatile saves
193
194
195 //////////////////////////////////////////////////////////////////////
196 //
197 // SAVE_REGS
198 //
199 // Create a stack frame and save all argument registers in preparation
200 // for a function call.
201 //////////////////////////////////////////////////////////////////////
202
203 .macro SAVE_REGS
204
205 pushl %ebp
206 movl %esp, %ebp
207
208 subl $$(8+5*16), %esp
209
210 movdqa %xmm3, 4*16(%esp)
211 movdqa %xmm2, 3*16(%esp)
212 movdqa %xmm1, 2*16(%esp)
213 movdqa %xmm0, 1*16(%esp)
214
215 .endmacro
216
217
218 //////////////////////////////////////////////////////////////////////
219 //
220 // RESTORE_REGS
221 //
222 // Restore all argument registers and pop the stack frame created by
223 // SAVE_REGS.
224 //////////////////////////////////////////////////////////////////////
225
226 .macro RESTORE_REGS
227
228 movdqa 4*16(%esp), %xmm3
229 movdqa 3*16(%esp), %xmm2
230 movdqa 2*16(%esp), %xmm1
231 movdqa 1*16(%esp), %xmm0
232
233 leave
234
235 .endmacro
236 /////////////////////////////////////////////////////////////////////
237 //
238 // CacheLookup return-type, caller
239 //
240 // Locate the implementation for a selector in a class method cache.
241 //
242 // Takes:
243 // $0 = NORMAL, FPRET, STRET
244 // $1 = CALL, LOOKUP, GETIMP
245 // ecx = selector to search for
246 // edx = class to search
247 //
248 // On exit: ecx clobbered
249 // (found) calls or returns IMP in eax, eq/ne set for forwarding
250 // (not found) jumps to LCacheMiss, class still in edx
251 //
252 /////////////////////////////////////////////////////////////////////
253
254 .macro CacheHit
255
256 // CacheHit must always be preceded by a not-taken `jne` instruction
257 // in case the imp is _objc_msgForward_impcache.
258
259 // eax = found bucket
260
261 .if $1 == GETIMP
262 movl cached_imp(%eax), %eax // return imp
263 cmpl $$0, %eax
264 jz 9f // don't xor a nil imp
265 xorl %edx, %eax // xor the isa with the imp
266 9: ret
267
268 .else
269
270 .if $1 == CALL
271 xorl cached_imp(%eax), %edx // xor imp and isa
272 .if $0 != STRET
273 // ne already set for forwarding by `xor`
274 .else
275 cmp %eax, %eax // set eq for stret forwarding
276 .endif
277 jmp *%edx // call imp
278
279 .elseif $1 == LOOKUP
280 movl cached_imp(%eax), %eax // return imp
281 xorl %edx, %eax // xor isa into imp
282 ret
283
284 .else
285 .abort oops
286 .endif
287
288 .endif
289
290 .endmacro
291
292
293 .macro CacheLookup
294
295 movzwl cache_mask(%edx), %eax // eax = mask
296 andl %ecx, %eax // eax = SEL & mask
297 shll $$3, %eax // eax = offset = (SEL & mask) * 8
298 addl cache_buckets(%edx), %eax // eax = bucket = buckets+offset
299 cmpl cached_sel(%eax), %ecx // if (bucket->sel != SEL)
300 jne 1f // scan more
301 // The `jne` above sets flags for CacheHit
302 CacheHit $0, $1 // call or return imp
303
304 1:
305 // loop
306 cmpl $$1, cached_sel(%eax)
307 jbe 3f // if (bucket->sel <= 1) wrap or miss
308
309 addl $$8, %eax // bucket++
310 2:
311 cmpl cached_sel(%eax), %ecx // if (bucket->sel != sel)
312 jne 1b // scan more
313 // The `jne` above sets flags for CacheHit
314 CacheHit $0, $1 // call or return imp
315
316 3:
317 // wrap or miss
318 jb LCacheMiss_f // if (bucket->sel < 1) cache miss
319 // wrap
320 movl cached_imp(%eax), %eax // bucket->imp is really first bucket
321 jmp 2f
322
323 // Clone scanning loop to miss instead of hang when cache is corrupt.
324 // The slow path may detect any corruption and halt later.
325
326 1:
327 // loop
328 cmpl $$1, cached_sel(%eax)
329 jbe 3f // if (bucket->sel <= 1) wrap or miss
330
331 addl $$8, %eax // bucket++
332 2:
333 cmpl cached_sel(%eax), %ecx // if (bucket->sel != sel)
334 jne 1b // scan more
335 // The `jne` above sets flags for CacheHit
336 CacheHit $0, $1 // call or return imp
337
338 3:
339 // double wrap or miss
340 jmp LCacheMiss_f
341
342 .endmacro
343
344
345 /////////////////////////////////////////////////////////////////////
346 //
347 // MethodTableLookup NORMAL|STRET
348 //
349 // Takes:
350 // receiver (not struct objc_super) and selector on stack
351 // edx = class to search
352 //
353 // On exit: IMP in eax, eq/ne set for forwarding
354 //
355 /////////////////////////////////////////////////////////////////////
356
357 .macro MethodTableLookup
358 SAVE_REGS
359
360 .if $0 == NORMAL
361 movl self+4(%ebp), %eax
362 movl selector+4(%ebp), %ecx
363 .else
364 movl self_stret+4(%ebp), %eax
365 movl selector_stret+4(%ebp), %ecx
366 .endif
367
368 // lookUpImpOrForward(obj, sel, cls, LOOKUP_INITIALIZE | LOOKUP_RESOLVER)
369 movl $$3, 12(%esp) // LOOKUP_INITIALIZE | LOOKUP_RESOLVER
370 movl %edx, 8(%esp) // class
371 movl %ecx, 4(%esp) // selector
372 movl %eax, 0(%esp) // receiver
373 call _lookUpImpOrForward
374
375 // imp in eax
376
377 .if $0 == NORMAL
378 test %eax, %eax // set ne for stret forwarding
379 .else
380 cmp %eax, %eax // set eq for nonstret forwarding
381 .endif
382
383 RESTORE_REGS
384
385 .endmacro
386
387
388 /////////////////////////////////////////////////////////////////////
389 //
390 // NilTest return-type
391 //
392 // Takes: $0 = NORMAL or FPRET or STRET
393 // eax = receiver
394 //
395 // On exit: Loads non-nil receiver in eax and self(esp) or self_stret(esp),
396 // or returns zero.
397 //
398 // NilTestReturnZero return-type
399 //
400 // Takes: $0 = NORMAL or FPRET or STRET
401 // eax = receiver
402 //
403 // On exit: Loads non-nil receiver in eax and self(esp) or self_stret(esp),
404 // or returns zero.
405 //
406 // NilTestReturnIMP return-type
407 //
408 // Takes: $0 = NORMAL or FPRET or STRET
409 // eax = receiver
410 //
411 // On exit: Loads non-nil receiver in eax and self(esp) or self_stret(esp),
412 // or returns an IMP in eax that returns zero.
413 //
414 /////////////////////////////////////////////////////////////////////
415
416 .macro ZeroReturn
417 xorl %eax, %eax
418 xorl %edx, %edx
419 xorps %xmm0, %xmm0
420 xorps %xmm1, %xmm1
421 .endmacro
422
423 .macro ZeroReturnFPRET
424 fldz
425 .endmacro
426
427 .macro ZeroReturnSTRET
428 // empty
429 .endmacro
430
431 STATIC_ENTRY __objc_msgNil
432 ZeroReturn
433 ret
434 END_ENTRY __objc_msgNil
435
436 STATIC_ENTRY __objc_msgNil_fpret
437 ZeroReturnFPRET
438 ret
439 END_ENTRY __objc_msgNil_fpret
440
441 STATIC_ENTRY __objc_msgNil_stret
442 ZeroReturnSTRET
443 ret $4
444 END_ENTRY __objc_msgNil_stret
445
446
447 .macro NilTest
448 testl %eax, %eax
449 jz LNilTestSlow_f
450 LNilTestDone:
451 .endmacro
452
453 .macro NilTestReturnZero
454 .align 3
455 LNilTestSlow:
456
457 .if $0 == NORMAL
458 ZeroReturn
459 ret
460 .elseif $0 == FPRET
461 ZeroReturnFPRET
462 ret
463 .elseif $0 == STRET
464 ZeroReturnSTRET
465 ret $$4
466 .else
467 .abort oops
468 .endif
469 .endmacro
470
471 .macro NilTestReturnIMP
472 .align 3
473 LNilTestSlow:
474
475 call 1f
476 1: pop %eax
477 .if $0 == NORMAL
478 leal __objc_msgNil-1b(%eax), %eax
479 .elseif $0 == FPRET
480 leal __objc_msgNil_fpret-1b(%eax), %eax
481 .elseif $0 == STRET
482 leal __objc_msgNil_stret-1b(%eax), %eax
483 .else
484 .abort oops
485 .endif
486 ret
487 .endmacro
488
489
490 /********************************************************************
491 * IMP _cache_getImp(Class cls, SEL sel)
492 *
493 * If found, returns method implementation.
494 * If not found, returns NULL.
495 ********************************************************************/
496
497 STATIC_ENTRY _cache_getImp
498
499 // load the class and selector
500 movl selector(%esp), %ecx
501 movl self(%esp), %edx
502
503 CacheLookup NORMAL, GETIMP // returns IMP on success
504
505 LCacheMiss:
506 // cache miss, return nil
507 xorl %eax, %eax
508 ret
509
510 END_ENTRY _cache_getImp
511
512
513 /********************************************************************
514 *
515 * id objc_msgSend(id self, SEL _cmd, ...);
516 * IMP objc_msgLookup(id self, SEL _cmd, ...);
517 *
518 * objc_msgLookup ABI:
519 * IMP returned in eax
520 * Forwarding returned in Z flag
521 * edx reserved for our use but not used
522 *
523 ********************************************************************/
524
525 ENTRY _objc_msgSend
526 UNWIND _objc_msgSend, NoFrame
527
528 movl selector(%esp), %ecx
529 movl self(%esp), %eax
530
531 NilTest NORMAL
532
533 movl isa(%eax), %edx // class = self->isa
534 CacheLookup NORMAL, CALL // calls IMP on success
535
536 NilTestReturnZero NORMAL
537
538 LCacheMiss:
539 // isa still in edx
540 jmp __objc_msgSend_uncached
541
542 END_ENTRY _objc_msgSend
543
544
545 ENTRY _objc_msgLookup
546 UNWIND _objc_msgLookup, NoFrame
547
548 movl selector(%esp), %ecx
549 movl self(%esp), %eax
550
551 NilTest NORMAL
552
553 movl isa(%eax), %edx // class = self->isa
554 CacheLookup NORMAL, LOOKUP // returns IMP on success
555
556 NilTestReturnIMP NORMAL
557
558 LCacheMiss:
559 // isa still in edx
560 jmp __objc_msgLookup_uncached
561
562 END_ENTRY _objc_msgLookup
563
564
565 /********************************************************************
566 *
567 * id objc_msgSendSuper(struct objc_super *super, SEL _cmd, ...);
568 *
569 ********************************************************************/
570
571 ENTRY _objc_msgSendSuper
572 UNWIND _objc_msgSendSuper, NoFrame
573
574 movl selector(%esp), %ecx
575 movl super(%esp), %eax // struct objc_super
576 movl class(%eax), %edx // struct objc_super->class
577 movl receiver(%eax), %eax // struct objc_super->receiver
578 movl %eax, super(%esp) // replace super arg with receiver
579 CacheLookup NORMAL, CALL // calls IMP on success
580
581 LCacheMiss:
582 // class still in edx
583 jmp __objc_msgSend_uncached
584
585 END_ENTRY _objc_msgSendSuper
586
587
588 /********************************************************************
589 *
590 * id objc_msgSendSuper2(struct objc_super *super, SEL _cmd, ...);
591 * IMP objc_msgLookupSuper2(struct objc_super *super, SEL _cmd, ...);
592 *
593 ********************************************************************/
594
595 ENTRY _objc_msgSendSuper2
596 UNWIND _objc_msgSendSuper2, NoFrame
597
598 movl selector(%esp), %ecx
599 movl super(%esp), %eax // struct objc_super
600 movl class(%eax), %edx // struct objc_super->class
601 movl receiver(%eax), %eax // struct objc_super->receiver
602 movl %eax, super(%esp) // replace super arg with receiver
603 movl superclass(%edx), %edx // edx = objc_super->class->super_class
604 CacheLookup NORMAL, CALL // calls IMP on success
605
606 LCacheMiss:
607 // class still in edx
608 jmp __objc_msgSend_uncached
609
610 END_ENTRY _objc_msgSendSuper2
611
612
613 ENTRY _objc_msgLookupSuper2
614 UNWIND _objc_msgLookupSuper2, NoFrame
615
616 movl selector(%esp), %ecx
617 movl super(%esp), %eax // struct objc_super
618 movl class(%eax), %edx // struct objc_super->class
619 movl receiver(%eax), %eax // struct objc_super->receiver
620 movl %eax, super(%esp) // replace super arg with receiver
621 movl superclass(%edx), %edx // edx = objc_super->class->super_class
622 CacheLookup NORMAL, LOOKUP // returns IMP on success
623
624 LCacheMiss:
625 // class still in edx
626 jmp __objc_msgLookup_uncached
627
628 END_ENTRY _objc_msgLookupSuper2
629
630
631 /********************************************************************
632 *
633 * double objc_msgSend_fpret(id self, SEL _cmd, ...);
634 * IMP objc_msgLookup_fpret(id self, SEL _cmd, ...);
635 *
636 ********************************************************************/
637
638 ENTRY _objc_msgSend_fpret
639 UNWIND _objc_msgSend_fpret, NoFrame
640
641 movl selector(%esp), %ecx
642 movl self(%esp), %eax
643
644 NilTest FPRET
645
646 movl isa(%eax), %edx // class = self->isa
647 CacheLookup FPRET, CALL // calls IMP on success
648
649 NilTestReturnZero FPRET
650
651 LCacheMiss:
652 // class still in edx
653 jmp __objc_msgSend_uncached
654
655 END_ENTRY _objc_msgSend_fpret
656
657
658 ENTRY _objc_msgLookup_fpret
659 UNWIND _objc_msgLookup_fpret, NoFrame
660
661 movl selector(%esp), %ecx
662 movl self(%esp), %eax
663
664 NilTest FPRET
665
666 movl isa(%eax), %edx // class = self->isa
667 CacheLookup FPRET, LOOKUP // returns IMP on success
668
669 NilTestReturnIMP FPRET
670
671 LCacheMiss:
672 // class still in edx
673 jmp __objc_msgLookup_uncached
674
675 END_ENTRY _objc_msgLookup_fpret
676
677
678 /********************************************************************
679 *
680 * void objc_msgSend_stret(void *st_addr, id self, SEL _cmd, ...);
681 * IMP objc_msgLookup_stret(void *st_addr, id self, SEL _cmd, ...);
682 *
683 ********************************************************************/
684
685 ENTRY _objc_msgSend_stret
686 UNWIND _objc_msgSend_stret, NoFrame
687
688 movl selector_stret(%esp), %ecx
689 movl self_stret(%esp), %eax
690
691 NilTest STRET
692
693 movl isa(%eax), %edx // class = self->isa
694 CacheLookup STRET, CALL // calls IMP on success
695
696 NilTestReturnZero STRET
697
698 LCacheMiss:
699 // class still in edx
700 jmp __objc_msgSend_stret_uncached
701
702 END_ENTRY _objc_msgSend_stret
703
704
705 ENTRY _objc_msgLookup_stret
706 UNWIND _objc_msgLookup_stret, NoFrame
707
708 movl selector_stret(%esp), %ecx
709 movl self_stret(%esp), %eax
710
711 NilTest STRET
712
713 movl isa(%eax), %edx // class = self->isa
714 CacheLookup STRET, LOOKUP // returns IMP on success
715
716 NilTestReturnIMP STRET
717
718 LCacheMiss:
719 // class still in edx
720 jmp __objc_msgLookup_stret_uncached
721
722 END_ENTRY _objc_msgLookup_stret
723
724
725 /********************************************************************
726 *
727 * void objc_msgSendSuper_stret(void *st_addr, struct objc_super *super, SEL _cmd, ...);
728 *
729 ********************************************************************/
730
731 ENTRY _objc_msgSendSuper_stret
732 UNWIND _objc_msgSendSuper_stret, NoFrame
733
734 movl selector_stret(%esp), %ecx
735 movl super_stret(%esp), %eax // struct objc_super
736 movl class(%eax), %edx // struct objc_super->class
737 movl receiver(%eax), %eax // struct objc_super->receiver
738 movl %eax, super_stret(%esp) // replace super arg with receiver
739 CacheLookup STRET, CALL // calls IMP on success
740
741 LCacheMiss:
742 // class still in edx
743 jmp __objc_msgSend_stret_uncached
744
745 END_ENTRY _objc_msgSendSuper_stret
746
747
748 /********************************************************************
749 *
750 * void objc_msgSendSuper2_stret(void *st_addr, struct objc_super *super, SEL _cmd, ...);
751 * IMP objc_msgLookupSuper2_stret(void *st_addr, struct objc_super *super, SEL _cmd, ...);
752 *
753 ********************************************************************/
754
755 ENTRY _objc_msgSendSuper2_stret
756 UNWIND _objc_msgSendSuper2_stret, NoFrame
757
758 movl selector_stret(%esp), %ecx
759 movl super_stret(%esp), %eax // struct objc_super
760 movl class(%eax), %edx // struct objc_super->class
761 movl receiver(%eax), %eax // struct objc_super->receiver
762 movl %eax, super_stret(%esp) // replace super arg with receiver
763 mov superclass(%edx), %edx // edx = objc_super->class->super_class
764 CacheLookup STRET, CALL // calls IMP on success
765
766 // cache miss: go search the method lists
767 LCacheMiss:
768 // class still in edx
769 jmp __objc_msgSend_stret_uncached
770
771 END_ENTRY _objc_msgSendSuper2_stret
772
773
774 ENTRY _objc_msgLookupSuper2_stret
775 UNWIND _objc_msgLookupSuper2_stret, NoFrame
776
777 movl selector_stret(%esp), %ecx
778 movl super_stret(%esp), %eax // struct objc_super
779 movl class(%eax), %edx // struct objc_super->class
780 movl receiver(%eax), %eax // struct objc_super->receiver
781 movl %eax, super_stret(%esp) // replace super arg with receiver
782 mov superclass(%edx), %edx // edx = objc_super->class->super_class
783 CacheLookup STRET, LOOKUP // returns IMP on success
784
785 // cache miss: go search the method lists
786 LCacheMiss:
787 // class still in edx
788 jmp __objc_msgLookup_stret_uncached
789
790 END_ENTRY _objc_msgLookupSuper2_stret
791
792
793 /********************************************************************
794 *
795 * _objc_msgSend_uncached
796 * _objc_msgSend_stret_uncached
797 * _objc_msgLookup_uncached
798 * _objc_msgLookup_stret_uncached
799 *
800 * The uncached method lookup.
801 *
802 ********************************************************************/
803
804 STATIC_ENTRY __objc_msgSend_uncached
805 UNWIND __objc_msgSend_uncached, FrameWithNoSaves
806
807 // THIS IS NOT A CALLABLE C FUNCTION
808 // Out-of-band edx is the searched class
809
810 // edx is already the class to search
811 MethodTableLookup NORMAL
812 jmp *%eax // call imp
813
814 END_ENTRY __objc_msgSend_uncached
815
816
817 STATIC_ENTRY __objc_msgSend_stret_uncached
818 UNWIND __objc_msgSend_stret_uncached, FrameWithNoSaves
819
820 // THIS IS NOT A CALLABLE C FUNCTION
821 // Out-of-band edx is the searched class
822
823 // edx is already the class to search
824 MethodTableLookup STRET
825 jmp *%eax // call imp
826
827 END_ENTRY __objc_msgSend_stret_uncached
828
829
830 STATIC_ENTRY __objc_msgLookup_uncached
831 UNWIND __objc_msgLookup_uncached, FrameWithNoSaves
832
833 // THIS IS NOT A CALLABLE C FUNCTION
834 // Out-of-band edx is the searched class
835
836 // edx is already the class to search
837 MethodTableLookup NORMAL // eax = IMP
838 ret
839
840 END_ENTRY __objc_msgLookup_uncached
841
842
843 STATIC_ENTRY __objc_msgLookup_stret_uncached
844 UNWIND __objc_msgLookup_stret_uncached, FrameWithNoSaves
845
846 // THIS IS NOT A CALLABLE C FUNCTION
847 // Out-of-band edx is the searched class
848
849 // edx is already the class to search
850 MethodTableLookup STRET // eax = IMP
851 ret
852
853 END_ENTRY __objc_msgLookup_stret_uncached
854
855
856 /********************************************************************
857 *
858 * id _objc_msgForward(id self, SEL _cmd,...);
859 *
860 * _objc_msgForward and _objc_msgForward_stret are the externally-callable
861 * functions returned by things like method_getImplementation().
862 * _objc_msgForward_impcache is the function pointer actually stored in
863 * method caches.
864 *
865 ********************************************************************/
866
867 .non_lazy_symbol_pointer
868 L_forward_handler:
869 .indirect_symbol __objc_forward_handler
870 .long 0
871 L_forward_stret_handler:
872 .indirect_symbol __objc_forward_stret_handler
873 .long 0
874
875 STATIC_ENTRY __objc_msgForward_impcache
876 // Method cache version
877
878 // THIS IS NOT A CALLABLE C FUNCTION
879 // Out-of-band condition register is NE for stret, EQ otherwise.
880
881 je __objc_msgForward_stret
882 jmp __objc_msgForward
883
884 END_ENTRY _objc_msgForward_impcache
885
886
887 ENTRY __objc_msgForward
888 // Non-struct return version
889
890 call 1f
891 1: popl %edx
892 movl L_forward_handler-1b(%edx), %edx
893 jmp *(%edx)
894
895 END_ENTRY __objc_msgForward
896
897
898 ENTRY __objc_msgForward_stret
899 // Struct return version
900
901 call 1f
902 1: popl %edx
903 movl L_forward_stret_handler-1b(%edx), %edx
904 jmp *(%edx)
905
906 END_ENTRY __objc_msgForward_stret
907
908
909 ENTRY _objc_msgSend_debug
910 jmp _objc_msgSend
911 END_ENTRY _objc_msgSend_debug
912
913 ENTRY _objc_msgSendSuper2_debug
914 jmp _objc_msgSendSuper2
915 END_ENTRY _objc_msgSendSuper2_debug
916
917 ENTRY _objc_msgSend_stret_debug
918 jmp _objc_msgSend_stret
919 END_ENTRY _objc_msgSend_stret_debug
920
921 ENTRY _objc_msgSendSuper2_stret_debug
922 jmp _objc_msgSendSuper2_stret
923 END_ENTRY _objc_msgSendSuper2_stret_debug
924
925 ENTRY _objc_msgSend_fpret_debug
926 jmp _objc_msgSend_fpret
927 END_ENTRY _objc_msgSend_fpret_debug
928
929
930 ENTRY _objc_msgSend_noarg
931 jmp _objc_msgSend
932 END_ENTRY _objc_msgSend_noarg
933
934
935 ENTRY _method_invoke
936
937 // See if this is a small method.
938 testb $1, selector(%esp)
939 jnz L_method_invoke_small
940
941 // We can directly load the IMP from big methods.
942 movl selector(%esp), %ecx
943 movl method_name(%ecx), %edx
944 movl method_imp(%ecx), %eax
945 movl %edx, selector(%esp)
946 jmp *%eax
947
948 L_method_invoke_small:
949 // Small methods require a call to handle swizzling.
950 SAVE_REGS
951
952 movl selector+4(%ebp), %eax
953 movl %eax, 0(%esp)
954 call __method_getImplementationAndName
955 RESTORE_REGS
956 movl %edx, selector(%esp)
957 jmp *%eax
958
959 END_ENTRY _method_invoke
960
961
962 ENTRY _method_invoke_stret
963
964 // See if this is a small method.
965 testb $1, selector_stret(%esp)
966 jnz L_method_invoke_stret_small
967
968 // We can directly load the IMP from big methods.
969 movl selector_stret(%esp), %ecx
970 movl method_name(%ecx), %edx
971 movl method_imp(%ecx), %eax
972 movl %edx, selector_stret(%esp)
973 jmp *%eax
974
975 L_method_invoke_stret_small:
976 // Small methods require a call to handle swizzling.
977 SAVE_REGS
978
979 movl selector_stret+4(%ebp), %eax
980 movl %eax, 0(%esp)
981 call __method_getImplementationAndName
982 RESTORE_REGS
983 movl %edx, selector_stret(%esp)
984 jmp *%eax
985
986 END_ENTRY _method_invoke_stret
987
988
989 .section __DATA,__objc_msg_break
990 .long 0
991 .long 0
992
993 #endif