|
|
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 moninitobjc() to setup
26: | objective-C messages for profiling. The are made private_externs when in
27: | a shared library.
28: .reference _moninitobjc
29: .const
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 Lexit2
41: .long Lexit3
42: .long Lexit4
43: .long Lexit5
44: .long Lexit6
45: .long Lexit7
46: .long Lexit8
47: .long 0
48: #endif /* KERNEL */
49:
50: self = 4
51: selector = 8
52: cache = 32
53: buckets = 8
54: method_imp = 8
55:
56: | optimized for 68040: 27 clocks (best case) + 16 clocks / probe
57:
58: .text
59: .align 1
60: .globl _objc_msgSend
61: _objc_msgSend:
62: movel sp@(self),d0 | (1)
63: movel d0,a0 | (1)
64: andl __objc_multithread_mask,d0 | (1) if (_objc_multithread_mask == 0)
65: jne L1 | (2) goto lock;
66: tstl a0 | if (self == nil)
67: jne L11 | return nil
68: rts |
69: L1: movel a0@,a0 | (1) class = self->isa;
70: movel a1,sp@- | (2) (save a1)
71: movel a0@(cache),a1 | (1) cache = class->cache;
72: movel sp@(selector+4),d1 | (1) index = selector;
73: L2: andl a1@,d1 | (1) index &= cache->mask;
74: movel a1@(buckets,d1:l:4),d0 | (4) method = cache->buckets[index];
75: movel d0,a0 | (1) if (method == NULL)
76: jne L3 | (2) goto cache_miss;
77: jra L5 |
78: L3: movel sp@(selector+4),d0 | (1)
79: cmpl a0@,d0 | (1) if (method_name == selector)
80: jeq L4 | (2) goto cache_hit;
81: addql #1,d1 | index++
82: jra L2 | goto loop;
83: L4: movel a0@(method_imp),a0 | (1) imp = method->method_imp;
84: movel sp@+,a1 | (1) (restore a1)
85: Lexit1: jmp a0@ | (3) goto *imp;
86: .space 22 | /* area for moninitobjc to write */
87: L5: movel sp@(self+4),a0 | cache_miss:
88: movel sp@(selector+4),sp@- | imp =
89: movel a0@,sp@- | _class_lookupMethodAndLoadCache
90: jbsr __class_lookupMethodAndLoadCache | (class, selector);
91: addql #8,sp |
92: movel d0,a0 |
93: movel sp@+,a1 | (restore a1)
94: Lexit2: jmp a0@ | goto *imp;
95: .space 22 | /* area for moninitobjc to write */
96:
97:
98:
99: | locking version of objc_msgSend:
100:
101: L11: clrb _messageLock+1 | (workaround 040 bug)
102: tas _messageLock | mutex_lock (messageLock);
103: jpl L24 |
104: jra L11 |
105: L24: movel a0@,a0 | class = self->isa;
106: movel a1,sp@- | (save a1)
107: movel a0@(cache),a1 | cache = class->cache;
108: movel sp@(selector+4),d1 | index = selector;
109: L12: andl a1@,d1 | index &= cache->mask;
110: movel a1@(buckets,d1:l:4),d0 | method = cache->buckets[index];
111: movel d0,a0 | if (method == NULL)
112: jne L13 | goto cache_miss;
113: jra L15 |
114: L13: movel sp@(selector+4),d0 |
115: cmpl a0@,d0 | if (method_name == selector)
116: jeq L14 | goto cache_hit;
117: addql #1,d1 | index++
118: jra L12 | goto loop;
119: L14: movel a0@(method_imp),a0 | imp = method->method_imp;
120: movel sp@+,a1 | (restore a1)
121: clrb _messageLock | mutex_unlock (messageLock);
122: Lexit3: jmp a0@ | goto *imp;
123: .space 22 | /* area for moninitobjc to write */
124: L15: movel sp@(self+4),a0 | cache_miss:
125: movel sp@(selector+4),sp@- | imp =
126: movel a0@,sp@- | _class_lookupMethodAndLoadCache
127: jbsr __class_lookupMethodAndLoadCache | (class, selector);
128: addql #8,sp |
129: movel d0,a0 |
130: movel sp@+,a1 | (restore a1)
131: clrb _messageLock | mutex_unlock (messageLock);
132: Lexit4: jmp a0@ | goto *imp;
133: .space 22 | /* area for moninitobjc to write */
134:
135:
136:
137: caller = 4
138:
139: | optimized for 68040: 31 clocks (best case) + 16 clocks / probe
140:
141: .align 1
142: .globl _objc_msgSendSuper
143: _objc_msgSendSuper:
144: tstl __objc_multithread_mask | (1) if (_objc_multithread_mask == 0)
145: jne L20 | (2) goto lock;
146: jra L21 |
147: L20: movel sp@(caller),a0 | (1)
148: movel a2,sp@- | (2) (save a2)
149: movel a0@+,sp@(self+4) | (2) self = caller->receiver;
150: movel a0@,a2 | (1) class = caller->class;
151: movel a1,sp@- | (2) (save a1)
152: movel a2@(cache),a1 | (1) cache = class->cache;
153: movel sp@(selector+8),d1 | (1) index = selector;
154: L6: andl a1@,d1 | (1) index &= cache->mask;
155: movel a1@(buckets,d1:l:4),d0 | (4) method = cache->buckets[index];
156: movel d0,a0 | (1) if (method == NULL)
157: jne L7 | (2) goto cache_miss;
158: jra L9 |
159: L7: movel sp@(selector+8),d0 | (1)
160: cmpl a0@,d0 | (1) if (method_name == selector)
161: jeq L8 | (2) goto cache_hit;
162: addql #1,d1 | index++
163: jra L6 | goto loop;
164: L8: movel a0@(method_imp),a0 | (1) imp = method->method_imp;
165: movel sp@+,a1 | (1) (restore a1)
166: movel sp@+,a2 | (1) (restore a2)
167: Lexit5: jmp a0@ | (3) goto *imp;
168: .space 22 | /* area for moninitobjc to write */
169: L9: movel sp@(selector+8),sp@- | imp =
170: movel a2,sp@- | _class_lookupMethodAndLoadCache
171: jbsr __class_lookupMethodAndLoadCache | (class, selector);
172: addql #8,sp |
173: movel d0,a0 |
174: movel sp@+,a1 | (restore a1)
175: movel sp@+,a2 | (restore a2)
176: Lexit6: jmp a0@ | goto *imp;
177: .space 22 | /* area for moninitobjc to write */
178:
179:
180:
181: | locking version of objc_msgSendSuper:
182:
183: L21: clrb _messageLock+1 | (workaround 040 bug)
184: tas _messageLock | mutex_lock (messageLock);
185: jpl L27 |
186: jra L21 |
187: L27: movel sp@(caller),a0 |
188: movel a2,sp@- | (save a2)
189: movel a0@+,sp@(self+4) | self = caller->receiver;
190: movel a0@,a2 | class = caller->class;
191: movel a1,sp@- | (save a1)
192: movel a2@(cache),a1 | cache = class->cache;
193: movel sp@(selector+8),d1 | index = selector;
194: L16: andl a1@,d1 | index &= cache->mask;
195: movel a1@(buckets,d1:l:4),d0 | method = cache->buckets[index];
196: movel d0,a0 | if (method == NULL)
197: jne L17 | goto cache_miss;
198: jra L19 |
199: L17: movel sp@(selector+8),d0 |
200: cmpl a0@,d0 | if (method_name == selector)
201: jeq L18 | goto cache_hit;
202: addql #1,d1 | index++
203: jra L16 | goto loop;
204: L18: movel a0@(method_imp),a0 | imp = method->method_imp;
205: movel sp@+,a1 | (restore a1)
206: movel sp@+,a2 | (restore a2)
207: clrb _messageLock | mutex_unlock (messageLock);
208: Lexit7: jmp a0@ | goto *imp;
209: .space 22 | /* area for moninitobjc to write */
210: L19: movel sp@(selector+8),sp@- | imp =
211: movel a2,sp@- | _class_lookupMethodAndLoadCache
212: jbsr __class_lookupMethodAndLoadCache | (class, selector);
213: addql #8,sp |
214: movel d0,a0 |
215: movel sp@+,a1 | (restore a1)
216: movel sp@+,a2 | (restore a2)
217: clrb _messageLock | mutex_unlock (messageLock);
218: Lexit8: jmp a0@ | goto *imp;
219: .space 22 | /* area for moninitobjc to write */
220:
221:
222: .objc_meth_var_names
223: .align 1
224: L30: .ascii "forward::\0"
225:
226: .objc_message_refs
227: .align 2
228: L31: .long L30
229:
230: .cstring
231: .align 1
232: L32: .ascii "Does not recognize selector %s\0"
233:
234: .text
235: .align 1
236: .globl __objc_msgForward
237: __objc_msgForward:
238: linkw a6,#0x0 | set up frame pointer
239: movel sp@(selector+4),d0 | +n accounts for sp pushes
240: cmpl L31,d0 | if (sel == @selector (forward::))
241: bne L33 |
242: pea L30 | __objc_error (self,
243: pea L32 | _errDoesntRecognize
244: movel sp@(self+12),sp@- | "forward::");
245: bsr ___objc_error |
246: L33: pea sp@(self+4) | return [self forward: sel : &self];
247: movel d0,sp@- |
248: movel L31,sp@- |
249: movel sp@(self+16),sp@- |
250: bsr _objc_msgSend |
251: unlk a6 | clear frame pointer
252: rts |
253:
254:
255: size = 12
256: args = 16
257:
258: .text
259: .align 1
260: .globl _objc_msgSendv
261: _objc_msgSendv:
262: linkw a6,#0 |
263: movel a6@(size+4),d0 |
264: addql #3,d0 | size = round_up (size, 4);
265: andl #0xfffffffc,d0 |
266: movel a6@(args+4),a0 |
267: addl d0,a0 | arg_ptr = &args[size];
268: subql #8,d0 | size -= 8;
269: ble L35 | while (size > 0)
270: L34: movel a0@-,sp@- | *--sp = *--arg_ptr;
271: subql #4,d0 | size -= 4;
272: bgt L34 |
273: L35: movel a6@(selector+4),sp@- |
274: movel a6@(self+4),sp@- | objc_msgSend (self, selector, ...);
275: bsr _objc_msgSend |
276: unlk a6 | (deallocate variable storage)
277: rts |
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.