|
|
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: // Objective-C message dispatching for the i386 ! 51: ! 52: // arguments ! 53: self = 4 ! 54: selector = 8 ! 55: // structure indices ! 56: isa = 0 ! 57: cache = 32 ! 58: buckets = 8 ! 59: mask = 0 ! 60: method_name = 0 ! 61: method_imp = 8 ! 62: ! 63: // Objective-C method send ! 64: ! 65: .text ! 66: .globl _objc_msgSend ! 67: .align 4 ! 68: _objc_msgSend: ! 69: movl self(%esp), %eax ! 70: movl %eax, %ecx ! 71: andl __objc_multithread_mask, %ecx ! 72: je L1nil_or_multi ! 73: ! 74: // load variables and save caller registers. ! 75: // Overlapped to prevent AGI ! 76: movl selector(%esp), %ecx // (1) ! 77: movl isa(%eax), %eax // (1) class = self->isa; ! 78: pushl %edi // (1) ! 79: movl cache(%eax), %eax // (1) cache = class->cache; ! 80: pushl %esi // (1) ! 81: ! 82: lea buckets(%eax), %edi // (1) buckets = &cache->buckets; ! 83: movl mask(%eax), %esi // (1) mask = cache->mask; ! 84: movl %ecx, %edx // (1) index = selector; ! 85: ! 86: L1probe_cache: ! 87: andl %esi, %edx // (1) index &= mask; ! 88: movl (%edi, %edx, 4), %eax // (2) method_name = buckets[index]; ! 89: ! 90: orl %eax, %eax // (1) if (method != NULL) { ! 91: je L1cache_miss // (1) ! 92: cmpl method_name(%eax), %ecx // (1) method_name = method->name; ! 93: jne L1not_the_method // (1) if (method_name == selector) { ! 94: movl method_imp(%eax), %eax // (1) imp = method->method_imp; ! 95: popl %esi // (1) ! 96: popl %edi // (1) ! 97: Lexit1: jmp *%eax // (1) goto *imp; ! 98: .space 17 // area for moninitobjc to write ! 99: // } ! 100: L1not_the_method: ! 101: inc %edx // (1) index++; ! 102: jmp L1probe_cache // (1) } ! 103: ! 104: .align 4, 0x90 ! 105: L1cache_miss: ! 106: // restore caller registers ! 107: popl %esi // (1) ! 108: popl %edi // (1) ! 109: ! 110: movl self(%esp), %eax // (1) ! 111: movl isa(%eax), %eax // (1) ! 112: pushl %ecx // (1) ! 113: pushl %eax ! 114: call __class_lookupMethodAndLoadCache ! 115: addl $8, %esp ! 116: Lexit2: jmp *%eax ! 117: .space 17 // area for moninitobjc to write ! 118: ! 119: ! 120: L1nil_or_multi: ! 121: orl %eax,%eax ! 122: jne L1multi_msgSend ! 123: ret ! 124: ! 125: ! 126: // locking version of send - its the same except for the lock/clear ! 127: .align 4 ! 128: L1multi_msgSend: ! 129: // spin lock ! 130: movl $1, %ecx ! 131: leal _messageLock, %eax ! 132: L11spin: ! 133: xchgl %ecx, (%eax) ! 134: cmpl $0, %ecx ! 135: jne L11spin ! 136: ! 137: // load variables and save caller registers. ! 138: // Overlapped to prevent AGI ! 139: movl self(%esp), %eax // (1) ! 140: movl selector(%esp), %ecx // (1) ! 141: movl isa(%eax), %eax // (1) class = self->isa; ! 142: pushl %edi // (1) ! 143: movl cache(%eax), %eax // (1) cache = class->cache; ! 144: pushl %esi // (1) ! 145: ! 146: lea buckets(%eax), %edi // (1) buckets = &cache->buckets; ! 147: movl mask(%eax), %esi // (1) mask = cache->mask; ! 148: movl %ecx, %edx // (1) index = selector; ! 149: ! 150: L11probe_cache: ! 151: andl %esi, %edx // (1) index &= mask; ! 152: movl (%edi, %edx, 4), %eax // (2) method_name = buckets[index]; ! 153: ! 154: orl %eax, %eax // (1) if (method != NULL) { ! 155: je L11cache_miss // (1) ! 156: cmpl method_name(%eax), %ecx // (1) method_name = method->name; ! 157: jne L11not_the_method // (1) if (method_name == selector) { ! 158: movl method_imp(%eax), %eax // (1) imp = method->method_imp; ! 159: popl %esi // (1) ! 160: popl %edi // (1) ! 161: movl $0, _messageLock // (1) unlock ! 162: Lexit3: jmp *%eax // (1) goto *imp; ! 163: .space 17 // area for moninitobjc to write ! 164: // } ! 165: L11not_the_method: ! 166: inc %edx // (1) index++; ! 167: jmp L11probe_cache // (1) } ! 168: ! 169: .align 4, 0x90 ! 170: L11cache_miss: ! 171: // restore caller registers ! 172: popl %esi // (1) ! 173: popl %edi // (1) ! 174: ! 175: movl self(%esp), %eax // (1) ! 176: movl isa(%eax), %eax // (1) ! 177: pushl %ecx // (1) ! 178: pushl %eax ! 179: call __class_lookupMethodAndLoadCache ! 180: addl $8, %esp ! 181: movl $0, _messageLock // (1) unlock ! 182: Lexit4: jmp *%eax ! 183: .space 17 // area for moninitobjc to write ! 184: ! 185: ! 186: ! 187: ! 188: // Objective-C Super Send ! 189: ! 190: // arguments ! 191: caller = 4 ! 192: // structure elements ! 193: reciever = 0 ! 194: class = 4 ! 195: ! 196: .globl _objc_msgSendSuper ! 197: .align 4 ! 198: _objc_msgSendSuper: ! 199: movl __objc_multithread_mask, %eax // (1) ! 200: andl %eax, %eax // (1) if (multi) ! 201: je L2multi_msgSuperSend // (1) goto locking version ! 202: ! 203: movl caller(%esp), %eax // (1) ! 204: movl selector(%esp), %ecx // (1) ! 205: ! 206: // load variables and save caller registers. ! 207: // Overlapped to prevent AGI ! 208: movl class(%eax), %eax // (1) class = caller->class; ! 209: pushl %edi // (1) ! 210: movl cache(%eax), %eax // (1) cache = class->cache; ! 211: pushl %esi // (1) ! 212: ! 213: lea buckets(%eax), %edi // (1) buckets = &cache->buckets; ! 214: movl mask(%eax), %esi // (1) mask = cache->mask; ! 215: movl %ecx, %edx // (1) index = selector; ! 216: ! 217: L2probe_cache: ! 218: andl %esi, %edx // (1) index &= mask; ! 219: movl (%edi, %edx, 4), %eax // (2) method_name = buckets[index]; ! 220: ! 221: orl %eax, %eax // (1) if (method != NULL) { ! 222: je L2cache_miss // (1) ! 223: cmpl method_name(%eax), %ecx // (1) method_name = method->name; ! 224: jne L2not_the_method // (1) if (method_name == selector) { ! 225: ! 226: // clobber "caller" arg with "self" and get method pointer ! 227: movl caller+8(%esp), %edi // (1) ! 228: movl method_imp(%eax), %eax // (1) imp = method->method_imp; ! 229: movl reciever(%edi), %esi // (1) ! 230: movl %esi, caller+8(%esp) // (1) ! 231: ! 232: // restore caller registers ! 233: popl %esi // (1) ! 234: popl %edi // (1) ! 235: Lexit5: jmp *%eax // (1) goto *imp; ! 236: .space 17 // area for moninitobjc to write ! 237: // } ! 238: // .align 4, 0x90 ! 239: L2not_the_method: ! 240: inc %edx // (1) index++; ! 241: jmp L2probe_cache // (1) } ! 242: ! 243: .align 4, 0x90 ! 244: L2cache_miss: ! 245: // clobber "caller" arg with "reciever" ! 246: movl caller+8(%esp), %edi // (1) ! 247: movl reciever(%edi), %esi // (1) ! 248: movl %esi, caller+8(%esp) // (1) ! 249: ! 250: // get class argument ! 251: movl class(%edi), %eax // (1) ! 252: ! 253: // restore caller registers ! 254: popl %esi // (1) ! 255: popl %edi // (1) ! 256: ! 257: // push args (class, selector) ! 258: pushl %ecx // (1) ! 259: pushl %eax ! 260: call __class_lookupMethodAndLoadCache ! 261: addl $8, %esp ! 262: Lexit6: jmp *%eax ! 263: .space 17 // area for moninitobjc to write ! 264: ! 265: ! 266: ! 267: // locking version of super send ! 268: ! 269: .align 4 ! 270: L2multi_msgSuperSend: ! 271: // spin lock ! 272: movl $1, %ecx ! 273: leal _messageLock, %eax ! 274: L22spin: ! 275: xchgl %ecx, (%eax) ! 276: cmpl $0, %ecx ! 277: jne L22spin ! 278: ! 279: movl caller(%esp), %eax // (1) ! 280: movl selector(%esp), %ecx // (1) ! 281: ! 282: // load variables and save caller registers. ! 283: // Overlapped to prevent AGI ! 284: movl class(%eax), %eax // (1) class = caller->class; ! 285: pushl %edi // (1) ! 286: movl cache(%eax), %eax // (1) cache = class->cache; ! 287: pushl %esi // (1) ! 288: ! 289: lea buckets(%eax), %edi // (1) buckets = &cache->buckets; ! 290: movl mask(%eax), %esi // (1) mask = cache->mask; ! 291: movl %ecx, %edx // (1) index = selector; ! 292: ! 293: L22probe_cache: ! 294: andl %esi, %edx // (1) index &= mask; ! 295: movl (%edi, %edx, 4), %eax // (2) method_name = buckets[index]; ! 296: ! 297: orl %eax, %eax // (1) if (method != NULL) { ! 298: je L22cache_miss // (1) ! 299: cmpl method_name(%eax), %ecx // (1) method_name = method->name; ! 300: jne L22not_the_method // (1) if (method_name == selector) { ! 301: ! 302: // clobber "caller" arg with "self" and load method pointer ! 303: movl caller+8(%esp), %edi // (1) ! 304: movl method_imp(%eax), %eax // (1) imp = method->method_imp; ! 305: movl reciever(%edi), %esi // (1) ! 306: movl %esi, caller+8(%esp) // (1) ! 307: ! 308: // restore caller registers ! 309: popl %esi // (1) ! 310: popl %edi // (1) ! 311: movl $0, _messageLock // (1) unlock ! 312: Lexit7: jmp *%eax // (1) goto *imp; ! 313: .space 17 // area for moninitobjc to write ! 314: // } ! 315: // .align 4, 0x90 ! 316: L22not_the_method: ! 317: inc %edx // (1) index++; ! 318: jmp L22probe_cache // (1) } ! 319: ! 320: .align 4, 0x90 ! 321: L22cache_miss: ! 322: // clobber "caller" arg with "reciever" ! 323: movl caller+8(%esp), %edi // (1) ! 324: movl reciever(%edi), %esi // (1) ! 325: movl %esi, caller+8(%esp) // (1) ! 326: ! 327: // get class argument ! 328: movl class(%edi), %eax // (1) ! 329: ! 330: // restore caller registers ! 331: popl %esi // (1) ! 332: popl %edi // (1) ! 333: ! 334: // push args (class, selector) ! 335: pushl %ecx // (1) ! 336: pushl %eax ! 337: call __class_lookupMethodAndLoadCache ! 338: addl $8, %esp ! 339: movl $0, _messageLock // (1) unlock ! 340: Lexit8: jmp *%eax ! 341: .space 17 // area for moninitobjc to write ! 342: ! 343: ! 344: // Objective-C message forwarder ! 345: ! 346: .objc_meth_var_names ! 347: .align 2 ! 348: L30: .ascii "forward::\0" ! 349: ! 350: .objc_message_refs ! 351: .align 2 ! 352: L31: .long L30 ! 353: ! 354: .cstring ! 355: .align 2 ! 356: L32: .ascii "Does not recognize selector %s\0" ! 357: ! 358: .text ! 359: .align 4 ! 360: .globl __objc_msgForward ! 361: __objc_msgForward: ! 362: pushl %ebp ! 363: movl %esp,%ebp ! 364: movl (selector+4)(%esp), %eax ! 365: cmpl L31, %eax ! 366: je L33 ! 367: ! 368: leal (self+4)(%esp), %ecx ! 369: pushl %ecx ! 370: pushl %eax ! 371: movl L31, %ecx ! 372: pushl %ecx ! 373: pushl (self + 16)(%esp) ! 374: call _objc_msgSend ! 375: movl %ebp,%esp ! 376: popl %ebp ! 377: ret ! 378: ! 379: .align 4 ! 380: L33: ! 381: pushl $L30 ! 382: pushl $L32 ! 383: pushl (self + 12)(%esp) ! 384: call ___objc_error // volatile, will not return ! 385: ! 386: ! 387: ! 388: // Objective-C vararg message send ! 389: ! 390: // arguments ! 391: args = 16 ! 392: size = 12 ! 393: sel = 8 ! 394: self = 4 ! 395: ! 396: .text ! 397: .align 4 ! 398: .globl _objc_msgSendv ! 399: _objc_msgSendv: ! 400: pushl %ebp ! 401: movl %esp, %ebp ! 402: movl (args + 4)(%ebp), %edx ! 403: addl $8, %edx // skip self & selector ! 404: movl (size + 4)(%ebp), %ecx ! 405: shrl $2, %ecx ! 406: subl $2, %ecx // skip self & selector ! 407: jle L42 ! 408: L41: ! 409: decl %ecx ! 410: movl 0(%edx, %ecx, 4), %eax ! 411: pushl %eax ! 412: jg L41 ! 413: ! 414: L42: ! 415: movl (sel + 4)(%ebp), %ecx ! 416: pushl %ecx ! 417: movl (self + 4)(%ebp),%ecx ! 418: pushl %ecx ! 419: call _objc_msgSend ! 420: movl %ebp,%esp ! 421: popl %ebp ! 422: ret
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.