Annotation of XNU/libkern/c++/OSMetaClass.cpp, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * The contents of this file constitute Original Code as defined in and
        !             7:  * are subject to the Apple Public Source License Version 1.1 (the
        !             8:  * "License").  You may not use this file except in compliance with the
        !             9:  * License.  Please obtain a copy of the License at
        !            10:  * http://www.apple.com/publicsource and read it before using this file.
        !            11:  * 
        !            12:  * This Original Code and all software distributed under the License are
        !            13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            17:  * License for the specific language governing rights and limitations
        !            18:  * under the License.
        !            19:  * 
        !            20:  * @APPLE_LICENSE_HEADER_END@
        !            21:  */
        !            22: /* OSMetaClass.cpp created by gvdl on Fri 1998-11-17 */
        !            23: 
        !            24: #include <string.h>
        !            25: #include <sys/systm.h>
        !            26: 
        !            27: #include <libkern/OSReturn.h>
        !            28: 
        !            29: #include <libkern/c++/OSCollectionIterator.h>
        !            30: #include <libkern/c++/OSDictionary.h>
        !            31: #include <libkern/c++/OSMetaClass.h>
        !            32: #include <libkern/c++/OSArray.h>   
        !            33: #include <libkern/c++/OSSet.h>  
        !            34: #include <libkern/c++/OSSymbol.h>
        !            35: #include <libkern/c++/OSNumber.h>
        !            36: #include <libkern/c++/OSSerialize.h>
        !            37: #include <libkern/c++/OSLib.h>
        !            38: 
        !            39: enum {
        !            40:     kSuperIsCString = 0x80000000,
        !            41: };
        !            42: 
        !            43: __BEGIN_DECLS
        !            44: 
        !            45: #include <mach/etap_events.h>
        !            46: #include <kern/lock.h>
        !            47: 
        !            48: #ifdef DEBUG
        !            49: extern int debug_container_malloc_size;
        !            50: #define ACCUMSIZE(s) do { debug_container_malloc_size += (s); } while(0)
        !            51: #else
        !            52: #define ACCUMSIZE(s)
        !            53: #endif /* DEBUG */
        !            54: 
        !            55: __END_DECLS
        !            56: 
        !            57: static enum {
        !            58:     kCompletedBootstrap = 0,
        !            59:     kNoDictionaries = 1,
        !            60:     kMakingDictionaries = 2
        !            61: } sBootstrapState = kNoDictionaries;
        !            62: 
        !            63: static const int kClassCapacityIncrement = 40;
        !            64: static const int kKModCapacityIncrement = 10;
        !            65: static OSDictionary *sAllClassesDict, *sKModClassesDict;
        !            66: 
        !            67: static mutex_t *loadLock;
        !            68: static struct StalledData {
        !            69:     const char *kmodName;
        !            70:     OSReturn result;
        !            71:     unsigned int capacity;
        !            72:     unsigned int count;
        !            73:     OSMetaClass **classes;
        !            74: } *sStalled;
        !            75: 
        !            76: void OSMetaClass::logError(OSReturn result)
        !            77: {
        !            78:     const char *msg;
        !            79: 
        !            80:     switch (result) {
        !            81:     case kOSMetaClassNoInit:
        !            82:        msg="OSMetaClass::preModLoad wasn't called, runtime internal error";
        !            83:        break;
        !            84:     case kOSMetaClassNoDicts:
        !            85:        msg="Allocation failure for Metaclass internal dictionaries"; break;
        !            86:     case kOSMetaClassNoKModSet:
        !            87:        msg="Allocation failure for internal kmodule set"; break;
        !            88:     case kOSMetaClassNoInsKModSet:
        !            89:        msg="Can't insert the KMod set into the module dictionary"; break;
        !            90:     case kOSMetaClassNoSuper:
        !            91:        msg="Can't associate a class with its super class"; break;
        !            92:     case kOSMetaClassInstNoSuper:
        !            93:        msg="Instance construction, unknown super class."; break;
        !            94:     default:
        !            95:     case kOSMetaClassInternal:
        !            96:        msg="runtime internal error"; break;
        !            97:     case kOSReturnSuccess:
        !            98:        return;
        !            99:     }
        !           100:     printf("%s\n", msg);
        !           101: }
        !           102: 
        !           103: OSMetaClass::OSMetaClass(const char *inClassName,
        !           104:                         const char *inSuperClassName,
        !           105:                         unsigned int inClassSize)
        !           106: {
        !           107:     instanceCount = 0;
        !           108:     classSize = inClassSize;
        !           109:     if (inSuperClassName && *inSuperClassName) {
        !           110:        superClass = (OSMetaClass *) inSuperClassName;
        !           111:        classSize |= kSuperIsCString;
        !           112:     }
        !           113:     else
        !           114:        superClass = 0;
        !           115: 
        !           116:     className = (const OSSymbol *) inClassName;
        !           117: 
        !           118:     if (!sStalled) {
        !           119:        printf("OSMetaClass::preModLoad wasn't called for %s, "
        !           120:               "runtime internal error\n", inClassName);
        !           121:     } else if (!sStalled->result) {
        !           122:        // Grow stalled array if neccessary
        !           123:        if (sStalled->count >= sStalled->capacity) {
        !           124:            OSMetaClass **oldStalled = sStalled->classes;
        !           125:            int oldSize = sStalled->capacity * sizeof(OSMetaClass *);
        !           126:            int newSize = oldSize
        !           127:                        + kKModCapacityIncrement * sizeof(OSMetaClass *);
        !           128: 
        !           129:            sStalled->classes = (OSMetaClass **) kalloc(newSize);
        !           130:            if (!sStalled->classes) {
        !           131:                sStalled->classes = oldStalled;
        !           132:                sStalled->result = kOSMetaClassNoTempData;
        !           133:                return;
        !           134:            }
        !           135: 
        !           136:            sStalled->capacity += kKModCapacityIncrement;
        !           137:            memmove(sStalled->classes, oldStalled, oldSize);
        !           138:            kfree((vm_offset_t)oldStalled, oldSize);
        !           139:            ACCUMSIZE(newSize - oldSize);
        !           140:        }
        !           141: 
        !           142:        sStalled->classes[sStalled->count++] = this;
        !           143:     }
        !           144: }
        !           145: 
        !           146: OSMetaClass::~OSMetaClass()
        !           147: {
        !           148:     do {
        !           149:        OSCollectionIterator *iter;
        !           150: 
        !           151:        if (sAllClassesDict)
        !           152:            sAllClassesDict->removeObject(className);
        !           153: 
        !           154:        iter = OSCollectionIterator::withCollection(sKModClassesDict);
        !           155:        if (!iter)
        !           156:            break;
        !           157: 
        !           158:        OSSymbol *iterKey;
        !           159:        while ( (iterKey = (OSSymbol *) iter->getNextObject()) ) {
        !           160:            OSSet *kmodClassSet;
        !           161:            kmodClassSet = (OSSet *) sKModClassesDict->getObject(iterKey);
        !           162:            if (kmodClassSet && kmodClassSet->containsObject(this)) {
        !           163:                kmodClassSet->removeObject(this);
        !           164:                break;
        !           165:            }
        !           166:        }
        !           167:        iter->release();
        !           168:     } while (false);
        !           169: 
        !           170:     if (sStalled) {
        !           171:        unsigned int i;
        !           172: 
        !           173:        // First pass find class in stalled list
        !           174:        for (i = 0; i < sStalled->count; i++)
        !           175:            if (this == sStalled->classes[i])
        !           176:                break;
        !           177: 
        !           178:        if (i < sStalled->count) {
        !           179:            sStalled->count--;
        !           180:            if (i < sStalled->count)
        !           181:                memmove(&sStalled->classes[i], &sStalled->classes[i+1],
        !           182:                            (sStalled->count - i) * sizeof(OSMetaClass *));
        !           183:        }
        !           184:        return;
        !           185:     }
        !           186: }
        !           187: 
        !           188: // Don't do anything as these classes must be statically allocated
        !           189: void OSMetaClass::free() { }
        !           190: void OSMetaClass::retain() { }
        !           191: void OSMetaClass::release() { }
        !           192: 
        !           193: const char *OSMetaClass::getClassName() const
        !           194: {
        !           195:     return className->getCStringNoCopy();
        !           196: }
        !           197: 
        !           198: unsigned int OSMetaClass::getClassSize() const
        !           199: {
        !           200:     return classSize & ~kSuperIsCString;
        !           201: }
        !           202: 
        !           203: void *OSMetaClass::preModLoad(const char *kmodName)
        !           204: {
        !           205:     if (!loadLock) {
        !           206:         loadLock = mutex_alloc(ETAP_IO_AHA);
        !           207:        _mutex_lock(loadLock);
        !           208:     }
        !           209:     else
        !           210:        _mutex_lock(loadLock);
        !           211: 
        !           212:     sStalled = (StalledData *) kalloc(sizeof(*sStalled));
        !           213:     if (sStalled) {
        !           214:        sStalled->classes  = (OSMetaClass **)
        !           215:                        kalloc(kKModCapacityIncrement * sizeof(OSMetaClass *));
        !           216:        if (!sStalled->classes) {
        !           217:            kfree((vm_offset_t) sStalled, sizeof(*sStalled));
        !           218:            return 0;
        !           219:        }
        !           220:        ACCUMSIZE((kKModCapacityIncrement * sizeof(OSMetaClass *)) + sizeof(*sStalled));
        !           221: 
        !           222:         sStalled->result   = kOSReturnSuccess;
        !           223:        sStalled->capacity = kKModCapacityIncrement;
        !           224:        sStalled->count    = 0;
        !           225:        sStalled->kmodName = kmodName;
        !           226:        bzero(sStalled->classes, kKModCapacityIncrement * sizeof(OSMetaClass *));
        !           227:     }
        !           228: 
        !           229:     return sStalled;
        !           230: }
        !           231: 
        !           232: bool OSMetaClass::checkModLoad(void *loadHandle)
        !           233: {
        !           234:     return sStalled && loadHandle == sStalled
        !           235:        && sStalled->result == kOSReturnSuccess;
        !           236: }
        !           237: 
        !           238: static inline const OSSymbol *copySymbol(bool copy, const char *cString)
        !           239: {
        !           240:     if (copy)
        !           241:        return OSSymbol::withCString(cString);
        !           242:     else
        !           243:        return OSSymbol::withCStringNoCopy(cString);
        !           244: }
        !           245: 
        !           246: OSReturn OSMetaClass::postModLoad(void *loadHandle)
        !           247: {
        !           248:     OSReturn result = kOSReturnSuccess;
        !           249:     OSSet *kmodSet = 0;
        !           250: 
        !           251:     if (!sStalled || loadHandle != sStalled) {
        !           252:        logError(kOSMetaClassInternal);
        !           253:        return kOSMetaClassInternal;
        !           254:     }
        !           255: 
        !           256:     if (sStalled->result)
        !           257:        result = sStalled->result;
        !           258:     else switch (sBootstrapState) {
        !           259:     case kNoDictionaries:
        !           260:        sBootstrapState = kMakingDictionaries;
        !           261:        // No break; fall through
        !           262: 
        !           263:     case kMakingDictionaries:
        !           264:        sKModClassesDict = OSDictionary::withCapacity(kKModCapacityIncrement);
        !           265:        sAllClassesDict = OSDictionary::withCapacity(kClassCapacityIncrement);
        !           266:        if (!sAllClassesDict || !sKModClassesDict) {
        !           267:            result = kOSMetaClassNoDicts;
        !           268:            break;
        !           269:        }
        !           270:        // No break; fall through
        !           271: 
        !           272:     case kCompletedBootstrap:
        !           273:     {
        !           274:        bool copyStrings = (0 != strcmp("__kernel__", sStalled->kmodName));
        !           275: 
        !           276:        if (!sStalled->count)
        !           277:            break;      // Nothing to do so just get out
        !           278: 
        !           279:        kmodSet = OSSet::withCapacity(sStalled->count);
        !           280:        if (!kmodSet) {
        !           281:            result = kOSMetaClassNoKModSet;
        !           282:            break;
        !           283:        }
        !           284: 
        !           285:        if (!sKModClassesDict->setObject(sStalled->kmodName, kmodSet)) {
        !           286:            result = kOSMetaClassNoInsKModSet;
        !           287:            break;
        !           288:        }
        !           289: 
        !           290:        // First pass symbolling strings and inserting classes in dictionary
        !           291:        for (unsigned int i = 0; i < sStalled->count; i++) {
        !           292:            OSMetaClass *me = sStalled->classes[i];
        !           293: 
        !           294:            me->className = copySymbol(copyStrings,
        !           295:                                       (const char *) me->className);
        !           296:            if (me->classSize & kSuperIsCString)
        !           297:                me->superClass = (OSMetaClass *)
        !           298:                    copySymbol(copyStrings, (const char *) me->superClass);
        !           299: 
        !           300:            sAllClassesDict->setObject(me->className, me);
        !           301:            kmodSet->setObject(me);
        !           302:        }
        !           303: 
        !           304:        // Second pass to connect up superclasses.
        !           305:        for (unsigned int i = 0; !result && i < sStalled->count; i++) {
        !           306:            OSMetaClass *me = sStalled->classes[i];
        !           307:            OSSymbol *superSym;
        !           308: 
        !           309:            if (me->classSize & kSuperIsCString) {
        !           310: 
        !           311:                me->classSize &= ~kSuperIsCString;
        !           312:                superSym = (OSSymbol *) me->superClass;
        !           313:                me->superClass = (OSMetaClass *)
        !           314:                                    sAllClassesDict->getObject(superSym);
        !           315:                superSym->release();
        !           316:                if (!me->superClass)
        !           317:                    result = kOSMetaClassNoSuper;
        !           318:            }
        !           319:        }
        !           320:        sBootstrapState = kCompletedBootstrap;
        !           321:        break;
        !           322:     }
        !           323: 
        !           324:     default:
        !           325:        result = kOSMetaClassInternal;
        !           326:        break;
        !           327:     }
        !           328: 
        !           329:     if (kmodSet)
        !           330:        kmodSet->release();
        !           331: 
        !           332:     if (sStalled) {
        !           333:        ACCUMSIZE(-(sStalled->capacity * sizeof(OSMetaClass *)
        !           334:                     + sizeof(*sStalled)));
        !           335:        kfree((vm_offset_t) sStalled->classes,
        !           336:              sStalled->capacity * sizeof(OSMetaClass *));
        !           337:        kfree((vm_offset_t) sStalled, sizeof(*sStalled));
        !           338:        sStalled = 0;
        !           339:     }
        !           340: 
        !           341:     logError(result);
        !           342:     mutex_unlock(loadLock);
        !           343:     return result;
        !           344: }
        !           345: 
        !           346: 
        !           347: void OSMetaClass::instanceConstructed() const
        !           348: {
        !           349:     if (sStalled && (classSize & kSuperIsCString) && superClass)
        !           350:     {
        !           351:        OSMetaClass *me = (OSMetaClass *) this;  // overide const this
        !           352:        const char * const superName = (const char *) superClass;
        !           353: 
        !           354:        // The superClass may be in the class dictionary already.
        !           355:        if (sBootstrapState == kCompletedBootstrap && sAllClassesDict)
        !           356:            me->superClass = (OSMetaClass *)
        !           357:                sAllClassesDict->getObject(superName);
        !           358:        else
        !           359:            me->superClass = 0;
        !           360: 
        !           361:        if (!me->superClass) {
        !           362:            // Oh dear we have to scan the stalled list and walk the
        !           363:            // the super class chain manually.
        !           364:            unsigned int i;
        !           365: 
        !           366:            // find superclass in stalled list
        !           367:            for (i = 0; i < sStalled->count; i++) {
        !           368:                if (0 == strcmp(superName,
        !           369:                                (const char *) sStalled->classes[i]->className))
        !           370:                    break;
        !           371:            }
        !           372: 
        !           373:            if (i < sStalled->count) {
        !           374:                me->superClass = sStalled->classes[i];
        !           375:                me->classSize &= ~kSuperIsCString;
        !           376:            }
        !           377:            else
        !           378:                sStalled->result = kOSMetaClassInstNoSuper;
        !           379: 
        !           380:        }
        !           381:     }
        !           382: 
        !           383:     if ((0 == instanceCount++) && superClass)
        !           384:        superClass->instanceConstructed();
        !           385: }
        !           386: 
        !           387: void OSMetaClass::instanceDestructed() const
        !           388: {
        !           389:     if ((1 == instanceCount--) && superClass)
        !           390:        superClass->instanceDestructed();
        !           391: 
        !           392:     if( ((int) instanceCount) < 0)
        !           393:        printf("%s: bad retain(%d)", getClassName(), instanceCount);
        !           394: }
        !           395: 
        !           396: bool OSMetaClass::modHasInstance(const char *kmodName)
        !           397: {
        !           398:     bool result = false;
        !           399: 
        !           400:     if (!loadLock) {
        !           401:         loadLock = mutex_alloc(ETAP_IO_AHA);
        !           402:        _mutex_lock(loadLock);
        !           403:     }
        !           404:     else
        !           405:        _mutex_lock(loadLock);
        !           406: 
        !           407:     do {
        !           408:        OSSet *kmodClasses;
        !           409:        OSCollectionIterator *iter;
        !           410:        OSMetaClass *checkClass;
        !           411: 
        !           412:        kmodClasses = OSDynamicCast(OSSet,
        !           413:                                    sKModClassesDict->getObject(kmodName));
        !           414:        if (!kmodClasses)
        !           415:            break;
        !           416: 
        !           417:        iter = OSCollectionIterator::withCollection(kmodClasses);
        !           418:        if (!iter)
        !           419:            break;
        !           420: 
        !           421:        while ( (checkClass = (OSMetaClass *) iter->getNextObject()) )
        !           422:            if (checkClass->getInstanceCount()) {
        !           423:                result = true;
        !           424:                break;
        !           425:            }
        !           426: 
        !           427:        iter->release();
        !           428:     } while (false);
        !           429: 
        !           430:     mutex_unlock(loadLock);
        !           431: 
        !           432:     return result;
        !           433: }
        !           434: 
        !           435: void OSMetaClass::reportModInstances(const char *kmodName)
        !           436: {
        !           437:     OSSet *kmodClasses;
        !           438:     OSCollectionIterator *iter;
        !           439:     OSMetaClass *checkClass;
        !           440: 
        !           441:     kmodClasses = OSDynamicCast(OSSet,
        !           442:                                 sKModClassesDict->getObject(kmodName));
        !           443:     if (!kmodClasses)
        !           444:        return;
        !           445: 
        !           446:     iter = OSCollectionIterator::withCollection(kmodClasses);
        !           447:     if (!iter)
        !           448:        return;
        !           449: 
        !           450:     while ( (checkClass = (OSMetaClass *) iter->getNextObject()) )
        !           451:        if (checkClass->getInstanceCount()) {
        !           452:            printf("%s: %s has %d instance(s)\n",
        !           453:                  kmodName,
        !           454:                  checkClass->getClassName(),
        !           455:                  checkClass->getInstanceCount());
        !           456:        }
        !           457: 
        !           458:     iter->release();
        !           459: }
        !           460: 
        !           461: const OSMetaClass *OSMetaClass::getMetaClassWithName(const OSSymbol *name)
        !           462: {
        !           463:     OSMetaClass *retMeta = 0;
        !           464: 
        !           465:     if (!name)
        !           466:        return 0;
        !           467: 
        !           468:     if (sAllClassesDict)
        !           469:        retMeta = (OSMetaClass *) sAllClassesDict->getObject(name);
        !           470: 
        !           471:     if (!retMeta && sStalled)
        !           472:     {
        !           473:        // Oh dear we have to scan the stalled list and walk the
        !           474:        // the stalled list manually.
        !           475:        const char *cName = name->getCStringNoCopy();
        !           476:        unsigned int i;
        !           477: 
        !           478:        // find class in stalled list
        !           479:        for (i = 0; i < sStalled->count; i++) {
        !           480:            retMeta = sStalled->classes[i];
        !           481:            if (0 == strcmp(cName, (const char *) retMeta->className))
        !           482:                break;
        !           483:        }
        !           484: 
        !           485:        if (i < sStalled->count)
        !           486:            retMeta = 0;
        !           487:     }
        !           488: 
        !           489:     return retMeta;
        !           490: }
        !           491: 
        !           492: const OSMetaClass *OSMetaClass::getMetaClassWithName(const OSString *name)
        !           493: {
        !           494:     const OSSymbol *tmpKey = OSSymbol::withString(name);
        !           495:     const OSMetaClass *ret = getMetaClassWithName(tmpKey);
        !           496: 
        !           497:     tmpKey->release();
        !           498:     return ret;
        !           499: }
        !           500: 
        !           501: const OSMetaClass *OSMetaClass::getMetaClassWithName(const char *name)
        !           502: {
        !           503:     const OSSymbol *tmpKey = OSSymbol::withCStringNoCopy(name);
        !           504:     const OSMetaClass *ret = getMetaClassWithName(tmpKey);
        !           505: 
        !           506:     tmpKey->release();
        !           507:     return ret;
        !           508: }
        !           509: 
        !           510: OSObject *OSMetaClass::allocClassWithName(const OSSymbol *name)
        !           511: {
        !           512:     const OSMetaClass * const meta = getMetaClassWithName(name);
        !           513: 
        !           514:     if (meta)
        !           515:        return meta->alloc();
        !           516: 
        !           517:     return 0;
        !           518: }
        !           519: 
        !           520: OSObject *OSMetaClass::allocClassWithName(const OSString *name)
        !           521: {
        !           522:     const OSMetaClass * const meta = getMetaClassWithName(name);
        !           523: 
        !           524:     if (meta)
        !           525:        return meta->alloc();
        !           526: 
        !           527:     return 0;
        !           528: }
        !           529: 
        !           530: OSObject *OSMetaClass::allocClassWithName(const char *name)
        !           531: {
        !           532:     const OSMetaClass * const meta = getMetaClassWithName(name);
        !           533: 
        !           534:     if (meta)
        !           535:        return meta->alloc();
        !           536: 
        !           537:     return 0;
        !           538: }
        !           539: 
        !           540: 
        !           541: OSObject *
        !           542: OSMetaClass::checkMetaCastWithName(const OSSymbol *name, const OSObject *in)
        !           543: {
        !           544:     const OSMetaClass * const meta = getMetaClassWithName(name);
        !           545: 
        !           546:     if (meta)
        !           547:        return meta->checkMetaCast(in);
        !           548: 
        !           549:     return 0;
        !           550: }
        !           551: 
        !           552: OSObject *
        !           553: OSMetaClass::checkMetaCastWithName(const OSString *name, const OSObject *in)
        !           554: {
        !           555:     const OSMetaClass * const meta = getMetaClassWithName(name);
        !           556: 
        !           557:     if (meta)
        !           558:        return meta->checkMetaCast(in);
        !           559: 
        !           560:     return 0;
        !           561: }
        !           562: 
        !           563: OSObject *
        !           564: OSMetaClass::checkMetaCastWithName(const char *name, const OSObject *in)
        !           565: {
        !           566:     const OSMetaClass * const meta = getMetaClassWithName(name);
        !           567: 
        !           568:     if (meta)
        !           569:        return meta->checkMetaCast(in);
        !           570: 
        !           571:     return 0;
        !           572: }
        !           573: 
        !           574: /*
        !           575: OSMetaClass::checkMetaCast
        !           576:     checkMetaCast(OSObject *check)
        !           577: 
        !           578: Check to see if the 'check' object has this object in it's metaclass chain.  Returns check if it is indeed a kind of the current meta class, 0 otherwise.
        !           579: 
        !           580: Generally this method is not invoked directly but is used to implement the OSObject::metaCast member function.
        !           581: 
        !           582: See also OSObject::metaCast
        !           583: 
        !           584:  */
        !           585: OSObject *OSMetaClass::checkMetaCast(const OSObject *check) const
        !           586: {
        !           587:     const OSMetaClass * const toMeta = this;
        !           588:     const OSMetaClass *fromMeta;
        !           589: 
        !           590:     for (fromMeta = check->getMetaClass(); ; fromMeta = fromMeta->superClass) {
        !           591:        if (toMeta == fromMeta)
        !           592:            return (OSObject *) check; // Discard const
        !           593: 
        !           594:        if (!fromMeta->superClass || (fromMeta->classSize & kSuperIsCString))
        !           595:            break;
        !           596:     }
        !           597: 
        !           598:     return 0;
        !           599: }
        !           600: 
        !           601: const OSMetaClass *OSMetaClass::getSuperClass() const
        !           602: {
        !           603:     return superClass;
        !           604: }
        !           605: 
        !           606: unsigned int OSMetaClass::getInstanceCount() const
        !           607: {
        !           608:     return instanceCount;
        !           609: }
        !           610: 
        !           611: void OSMetaClass::printInstanceCounts()
        !           612: {
        !           613:     OSCollectionIterator *classes;
        !           614:     OSSymbol            *className;
        !           615:     OSMetaClass                 *meta;
        !           616: 
        !           617:     classes = OSCollectionIterator::withCollection(sAllClassesDict);
        !           618:     if (!classes)
        !           619:        return;
        !           620: 
        !           621:     while( (className = (OSSymbol *)classes->getNextObject())) {
        !           622:        meta = (OSMetaClass *) sAllClassesDict->getObject(className);
        !           623:        assert(meta);
        !           624: 
        !           625:        printf("%24s count: %03d x 0x%03x = 0x%06x\n",
        !           626:            className->getCStringNoCopy(),
        !           627:            meta->getInstanceCount(),
        !           628:            meta->getClassSize(),
        !           629:            meta->getInstanceCount() * meta->getClassSize() );
        !           630:     }
        !           631:     printf("\n");
        !           632:     classes->release();
        !           633: }
        !           634: 
        !           635: OSDictionary * OSMetaClass::getClassDictionary()
        !           636: {
        !           637:     return sAllClassesDict;
        !           638: }
        !           639: 
        !           640: bool OSMetaClass::serialize(OSSerialize *s) const
        !           641: {
        !           642:     OSDictionary *     dict;
        !           643:     OSNumber *         off;
        !           644:     bool               ok = false;
        !           645: 
        !           646:     if (s->previouslySerialized(this)) return true;
        !           647: 
        !           648:     dict = 0;// IODictionary::withCapacity(2);
        !           649:     off = OSNumber::withNumber(getInstanceCount(), 32);
        !           650: 
        !           651:     if (dict) {
        !           652:        dict->setObject("InstanceCount", off );
        !           653:        ok = dict->serialize(s);
        !           654:     } else if( off)
        !           655:        ok = off->serialize(s);
        !           656: 
        !           657:     if (dict)
        !           658:        dict->release();
        !           659:     if (off)
        !           660:        off->release();
        !           661: 
        !           662:     return ok;
        !           663: }

unix.superglobalmegacorp.com

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