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