Annotation of objc/objc-msg-i386-lock.s, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.