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