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