|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.0 (the 'License'). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License."
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24: #ifndef KERNEL
25: # _objc_entryPoints and _objc_exitPoints are used by objc
26: # to get the critical egions for which method caches
27: # cannot be garbage collected.
28:
29: .data
30: .globl _objc_entryPoints
31: _objc_entryPoints:
32: .long _objc_msgSend
33: .long _objc_msgSendSuper
34: .long _objc_msgSendv
35: .long 0
36:
37: .globl _objc_exitPoints
38: _objc_exitPoints:
39: .long Lexit1
40: .long Lexit5
41: .long Lexit9
42: .long 0
43: #endif /* KERNEL */
44:
45: // Objective-C message dispatching for the i386
46:
47: // arguments
48: self = 4
49: selector = 8
50: // structure indices
51: isa = 0
52: cache = 32
53: buckets = 8
54: mask = 0
55: method_name = 0
56: method_imp = 8
57:
58: // Objective-C method send
59:
60: .text
61: .globl _objc_msgSend
62: .align 4
63: _objc_msgSend:
64: #ifdef PROFILE
65: pushl %ebp
66: movl %esp,%ebp
67: movl $LP0,%eax
68: call mcount
69: .data
70: .align 2
71: LP0:
72: .long 0
73: .text
74: movl %ebp,%esp
75: popl %ebp
76: #endif
77: movl self(%esp), %eax
78:
79: // if receiver is nil
80: orl %eax, %eax
81: je L1nil_or_multi
82:
83: // load variables and save caller registers.
84: // Overlapped to prevent AGI
85: movl selector(%esp), %ecx // (1)
86: movl isa(%eax), %eax // (1) class = self->isa;
87: pushl %edi // (1)
88: movl cache(%eax), %eax // (1) cache = class->cache;
89: pushl %esi // (1)
90:
91: lea buckets(%eax), %edi // (1) buckets = &cache->buckets;
92: movl mask(%eax), %esi // (1) mask = cache->mask;
93: movl %ecx, %edx // (1) index = selector;
94:
95: L1probe_cache:
96: andl %esi, %edx // (1) index &= mask;
97: movl (%edi, %edx, 4), %eax // (2) method_name = buckets[index];
98:
99: orl %eax, %eax // (1) if (method != NULL) {
100: je L1cache_miss // (1)
101: cmpl method_name(%eax), %ecx // (1) method_name = method->name;
102: jne L1not_the_method // (1) if (method_name == selector) {
103: movl method_imp(%eax), %eax // (1) imp = method->method_imp;
104: popl %esi // (1)
105: popl %edi // (1)
106: Lexit1: jmp *%eax // (1) goto *imp;
107: .space 17 // area for moninitobjc to write
108: // }
109: L1not_the_method:
110: inc %edx // (1) index++;
111: jmp L1probe_cache // (1) }
112:
113: .align 4, 0x90
114: L1cache_miss:
115: // restore caller registers
116: popl %esi // (1)
117: popl %edi // (1)
118:
119: movl self(%esp), %eax // (1)
120: movl isa(%eax), %eax // (1)
121: pushl %ecx // (1)
122: pushl %eax
123: call __class_lookupMethodAndLoadCache
124: addl $8, %esp
125: Lexit2: jmp *%eax
126: .space 17 // area for moninitobjc to write
127:
128:
129: L1nil_or_multi:
130: ret
131:
132:
133:
134:
135: // Objective-C Super Send
136:
137: // arguments
138: caller = 4
139: // structure elements
140: reciever = 0
141: class = 4
142:
143: .globl _objc_msgSendSuper
144: .align 4
145: _objc_msgSendSuper:
146: #ifdef PROFILE
147: pushl %ebp
148: movl %esp,%ebp
149: movl $LP1,%eax
150: call mcount
151: .data
152: .align 2
153: LP1:
154: .long 0
155: .text
156: movl %ebp,%esp
157: popl %ebp
158: #endif
159:
160: movl caller(%esp), %eax // (1)
161: movl selector(%esp), %ecx // (1)
162:
163: // load variables and save caller registers.
164: // Overlapped to prevent AGI
165: movl class(%eax), %eax // (1) class = caller->class;
166: pushl %edi // (1)
167: movl cache(%eax), %eax // (1) cache = class->cache;
168: pushl %esi // (1)
169:
170: lea buckets(%eax), %edi // (1) buckets = &cache->buckets;
171: movl mask(%eax), %esi // (1) mask = cache->mask;
172: movl %ecx, %edx // (1) index = selector;
173:
174: L2probe_cache:
175: andl %esi, %edx // (1) index &= mask;
176: movl (%edi, %edx, 4), %eax // (2) method_name = buckets[index];
177:
178: orl %eax, %eax // (1) if (method != NULL) {
179: je L2cache_miss // (1)
180: cmpl method_name(%eax), %ecx // (1) method_name = method->name;
181: jne L2not_the_method // (1) if (method_name == selector) {
182:
183: // clobber "caller" arg with "self" and get method pointer
184: movl caller+8(%esp), %edi // (1)
185: movl method_imp(%eax), %eax // (1) imp = method->method_imp;
186: movl reciever(%edi), %esi // (1)
187: movl %esi, caller+8(%esp) // (1)
188:
189: // restore caller registers
190: popl %esi // (1)
191: popl %edi // (1)
192: Lexit5: jmp *%eax // (1) goto *imp;
193: .space 17 // area for moninitobjc to write
194: // }
195: // .align 4, 0x90
196: L2not_the_method:
197: inc %edx // (1) index++;
198: jmp L2probe_cache // (1) }
199:
200: .align 4, 0x90
201: L2cache_miss:
202: // clobber "caller" arg with "reciever"
203: movl caller+8(%esp), %edi // (1)
204: movl reciever(%edi), %esi // (1)
205: movl %esi, caller+8(%esp) // (1)
206:
207: // get class argument
208: movl class(%edi), %eax // (1)
209:
210: // restore caller registers
211: popl %esi // (1)
212: popl %edi // (1)
213:
214: // push args (class, selector)
215: pushl %ecx // (1)
216: pushl %eax
217: call __class_lookupMethodAndLoadCache
218: addl $8, %esp
219: Lexit6: jmp *%eax
220: .space 17 // area for moninitobjc to write
221:
222:
223:
224: // Objective-C message forwarder
225:
226: .objc_meth_var_names
227: .align 2
228: L30: .ascii "forward::\0"
229:
230: .objc_message_refs
231: .align 2
232: L31: .long L30
233:
234: .cstring
235: .align 2
236: L32: .ascii "Does not recognize selector %s\0"
237:
238: .text
239: .align 4
240: .globl __objc_msgForward
241: __objc_msgForward:
242: pushl %ebp
243: movl %esp,%ebp
244: movl (selector+4)(%esp), %eax
245: cmpl L31, %eax
246: je L33
247:
248: leal (self+4)(%esp), %ecx
249: pushl %ecx
250: pushl %eax
251: movl L31, %ecx
252: pushl %ecx
253: pushl (self + 16)(%esp)
254: call _objc_msgSend
255: movl %ebp,%esp
256: popl %ebp
257: ret
258:
259: .align 4
260: L33:
261: pushl $L30
262: pushl $L32
263: pushl (self + 12)(%esp)
264: call ___objc_error // volatile, will not return
265:
266:
267:
268: // Objective-C vararg message send
269:
270: // arguments
271: args = 16
272: size = 12
273: sel = 8
274: self = 4
275:
276: .text
277: .align 4
278: .globl _objc_msgSendv
279: _objc_msgSendv:
280: pushl %ebp
281: movl %esp, %ebp
282: movl (args + 4)(%ebp), %edx
283: addl $8, %edx // skip self & selector
284: movl (size + 4)(%ebp), %ecx
285: shrl $2, %ecx
286: subl $2, %ecx // skip self & selector
287: jle L42
288: L41:
289: decl %ecx
290: movl 0(%edx, %ecx, 4), %eax
291: pushl %eax
292: jg L41
293:
294: L42:
295: movl (sel + 4)(%ebp), %ecx
296: pushl %ecx
297: movl (self + 4)(%ebp),%ecx
298: pushl %ecx
299: call _objc_msgSend
300: movl %ebp,%esp
301: popl %ebp
302: Lexit9:
303: ret
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.