|
|
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.