VirtualBox

Ignore:
Timestamp:
May 2, 2020 11:57:04 AM (5 years ago)
Author:
vboxsync
Message:

IPRT/errmsg-sorter.cpp: Custom status message structure packing to save a bit more space. bugref:9726

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/err/errmsg-sorter.cpp

    r84070 r84128  
    8181    /** Status code number. */
    8282    int             iCode;
     83    /** Index into the primary table (for multiple passes). */
     84    unsigned        idx1;
    8385} RTSTATUSMSGINT2;
    8486typedef RTSTATUSMSGINT2 *PRTSTATUSMSGINT2;
     87
     88
     89/** This used to determin minimum field sizes. */
     90typedef struct RTSTATUSMSGSTATS
     91{
     92    unsigned offMax;
     93    unsigned cchMax;
     94    unsigned cBitsOffset;
     95    unsigned cBitsLength;
     96} RTSTATUSMSGSTATS;
     97typedef RTSTATUSMSGSTATS *PRTSTATUSMSGSTATS;
    8598
    8699
     
    159172
    160173    return false;
     174}
     175
     176
     177DECLINLINE(void) GatherStringStats(PRTSTATUSMSGSTATS pStats, PBLDPROGSTRING pString)
     178{
     179    if (pStats->offMax < pString->offStrTab)
     180        pStats->offMax = pString->offStrTab;
     181    if (pStats->cchMax < pString->cchString)
     182        pStats->cchMax = (unsigned)pString->cchString;
     183}
     184
     185
     186DECLINLINE(unsigned) CalcBitsForValue(size_t uValue)
     187{
     188    unsigned cBits = 1;
     189    while (RT_BIT_64(cBits) < uValue && cBits < 64)
     190        cBits++;
     191    return cBits;
     192}
     193
     194
     195static void CalcBitsForStringStats(PRTSTATUSMSGSTATS pStats)
     196{
     197    pStats->cBitsOffset = CalcBitsForValue(pStats->offMax);
     198    pStats->cBitsLength = CalcBitsForValue(pStats->cchMax);
    161199}
    162200
     
    228266
    229267    static RTSTATUSMSGINT2 s_aStatusMsgs2[RT_ELEMENTS(g_aStatusMsgs)];
    230     size_t                 cStatusMsgs = 0;
    231     for (size_t i = 0; i < RT_ELEMENTS(g_aStatusMsgs); i++)
    232     {
     268    unsigned               cStatusMsgs = 0;
     269    for (unsigned i = 0; i < RT_ELEMENTS(g_aStatusMsgs); i++)
    233270        if (!g_aStatusMsgs[i].fDuplicate)
    234271        {
     272            s_aStatusMsgs2[cStatusMsgs].idx1      = i;
    235273            s_aStatusMsgs2[cStatusMsgs].iCode     = g_aStatusMsgs[i].iCode;
    236274            s_aStatusMsgs2[cStatusMsgs].pszDefine = g_aStatusMsgs[i].pszDefine;
    237275            BldProgStrTab_AddStringDup(&StrTab, &s_aStatusMsgs2[cStatusMsgs].Define, g_aStatusMsgs[i].pszDefine);
    238             if (enmMode != kMode_OnlyDefines)
    239             {
    240                 BldProgStrTab_AddStringDup(&StrTab, &s_aStatusMsgs2[cStatusMsgs].MsgShort, g_aStatusMsgs[i].pszMsgShort);
    241                 if (enmMode == kMode_All)
    242                     BldProgStrTab_AddStringDup(&StrTab, &s_aStatusMsgs2[cStatusMsgs].MsgFull, g_aStatusMsgs[i].pszMsgFull);
    243             }
    244276            cStatusMsgs++;
    245277        }
    246     }
     278
     279    if (enmMode != kMode_OnlyDefines)
     280        for (size_t i = 0; i < cStatusMsgs; i++)
     281            BldProgStrTab_AddStringDup(&StrTab, &s_aStatusMsgs2[i].MsgShort, g_aStatusMsgs[s_aStatusMsgs2[i].idx1].pszMsgShort);
     282
     283    if (enmMode == kMode_All)
     284        for (size_t i = 0; i < cStatusMsgs; i++)
     285            BldProgStrTab_AddStringDup(&StrTab, &s_aStatusMsgs2[i].MsgFull, g_aStatusMsgs[s_aStatusMsgs2[i].idx1].pszMsgFull);
    247286
    248287    if (!BldProgStrTab_CompileIt(&StrTab, true))
     
    256295    {
    257296        /*
     297         * .
     298         */
     299        RTSTATUSMSGSTATS Defines  = {0, 0, 0, 0};
     300        RTSTATUSMSGSTATS MsgShort = {0, 0, 0, 0};
     301        RTSTATUSMSGSTATS MsgFull  = {0, 0, 0, 0};
     302        for (size_t i = 0; i < cStatusMsgs; i++)
     303        {
     304            GatherStringStats(&Defines,  &s_aStatusMsgs2[i].Define);
     305            GatherStringStats(&MsgShort, &s_aStatusMsgs2[i].MsgShort);
     306            GatherStringStats(&MsgFull,  &s_aStatusMsgs2[i].MsgFull);
     307        }
     308        CalcBitsForStringStats(&Defines);
     309        CalcBitsForStringStats(&MsgShort);
     310        CalcBitsForStringStats(&MsgFull);
     311        printf(" Defines: max offset %#x -> %u bits, max length %#x -> bits %u\n",
     312               Defines.offMax, Defines.cBitsOffset, (unsigned)Defines.cchMax, Defines.cBitsLength);
     313        if (enmMode != kMode_OnlyDefines)
     314            printf("MsgShort: max offset %#x -> %u bits, max length %#x -> bits %u\n",
     315                   MsgShort.offMax, MsgShort.cBitsOffset, (unsigned)MsgShort.cchMax, MsgShort.cBitsLength);
     316        if (enmMode == kMode_All)
     317            printf(" MsgFull: max offset %#x -> %u bits, max length %#x -> bits %u\n",
     318                   MsgFull.offMax, MsgFull.cBitsOffset, (unsigned)MsgFull.cchMax, MsgFull.cBitsLength);
     319
     320        unsigned cBitsCodePos = CalcBitsForValue((size_t)s_aStatusMsgs2[cStatusMsgs - 1].iCode);
     321        unsigned cBitsCodeNeg = CalcBitsForValue((size_t)-s_aStatusMsgs2[0].iCode);
     322        unsigned cBitsCode    = RT_MAX(cBitsCodePos, cBitsCodeNeg) + 1;
     323        printf("Statuses: min %d, max %d -> %u bits\n",
     324               s_aStatusMsgs2[0].iCode, s_aStatusMsgs2[cStatusMsgs - 1].iCode, cBitsCode);
     325
     326        /*
    258327         * Print the table.
    259328         */
    260329        fprintf(pOut,
    261330                "\n"
     331                "#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)\n"
     332                "# pragma pack(1)\n"
     333                "#endif\n"
    262334                "typedef struct RTMSGENTRYINT\n"
    263                 "{\n"
    264                 "    uint32_t offDefine   : 20;\n"
    265                 "    uint32_t cchDefine   : 9;\n"
    266                 "%s"
    267                 "%s"
    268                 "    int32_t  iCode;\n"
     335                "{\n");
     336        /* 16 + 16 + 8 */
     337        bool fOptimalLayout = true;
     338        if (   enmMode == kMode_OnlyDefines
     339            && cBitsCode <= 16
     340            && Defines.cBitsOffset <= 16
     341            && Defines.cBitsLength <= 8)
     342            fprintf(pOut,
     343                    "    uint16_t offDefine; /* need %2u bits, max %#x */\n"
     344                    "    uint8_t  cchDefine; /* need %2u bits, max %#x */\n"
     345                    "    int16_t  iCode;     /* need %2u bits */\n",
     346                    Defines.cBitsOffset, Defines.offMax, Defines.cBitsLength, Defines.cchMax, cBitsCode);
     347        else if (   enmMode == kMode_NoFullMsg
     348                 && cBitsCode + Defines.cBitsOffset + Defines.cBitsLength + MsgShort.cBitsOffset + MsgShort.cBitsLength <= 64)
     349            fprintf(pOut,
     350                    "    uint64_t offDefine   : %2u; /* max %#x */\n"
     351                    "    uint64_t cchDefine   : %2u; /* max %#x */\n"
     352                    "    uint64_t offMsgShort : %2u; /* max %#x */\n"
     353                    "    uint64_t cchMsgShort : %2u; /* max %#x */\n"
     354                    "    int64_t  iCode       : %2u;\n",
     355                    Defines.cBitsOffset,  Defines.offMax,
     356                    Defines.cBitsLength,  Defines.cchMax,
     357                    MsgShort.cBitsOffset, MsgShort.offMax,
     358                    MsgShort.cBitsLength, MsgShort.cchMax,
     359                    cBitsCode);
     360        else if (   enmMode == kMode_All
     361                 &&   Defines.cBitsOffset  + Defines.cBitsLength
     362                    + MsgShort.cBitsOffset + MsgShort.cBitsLength
     363                    + MsgFull.cBitsOffset  + MsgFull.cBitsLength
     364                    + cBitsCode <= 96
     365                 && cBitsCode + Defines.cBitsLength + MsgShort.cBitsLength <= 32)
     366            fprintf(pOut,
     367                    "    uint64_t offDefine   : %2u; /* max %#x */\n"
     368                    "    uint64_t offMsgShort : %2u; /* max %#x */\n"
     369                    "    uint64_t offMsgFull  : %2u; /* max %#x */\n"
     370                    "    uint64_t cchMsgFull  : %2u; /* max %#x */\n"
     371                    "    int32_t  iCode       : %2u;\n"
     372                    "    uint32_t cchDefine   : %2u; /* max %#x */\n"
     373                    "    uint32_t cchMsgShort : %2u; /* max %#x */\n",
     374                    Defines.cBitsOffset,  Defines.offMax,
     375                    MsgShort.cBitsOffset, MsgShort.offMax,
     376                    MsgFull.cBitsOffset,  MsgFull.offMax,
     377                    MsgFull.cBitsLength,  MsgFull.cchMax,
     378                    cBitsCode,
     379                    Defines.cBitsLength,  Defines.cchMax,
     380                    MsgShort.cBitsLength, MsgShort.cchMax);
     381        else
     382        {
     383            fprintf(stderr, "%s: warning: Optimized structure layouts needs readjusting...\n", g_pszProgName);
     384            fOptimalLayout = false;
     385            fprintf(pOut,
     386                    "    uint32_t offDefine   : 23; /* need %u bits, max %#x */\n"
     387                    "    uint32_t cchDefine   :  9; /* need %u bits, max %#x */\n",
     388                    Defines.cBitsOffset, Defines.offMax, Defines.cBitsLength, Defines.cchMax);
     389            if (enmMode != kMode_OnlyDefines)
     390                fprintf(pOut,
     391                        "    uint32_t offMsgShort : 23; /* need %u bits, max %#x */\n"
     392                        "    uint32_t cchMsgShort :  9; /* need %u bits, max %#x */\n",
     393                        MsgShort.cBitsOffset, MsgShort.offMax, MsgShort.cBitsLength, MsgShort.offMax);
     394            if (enmMode == kMode_All)
     395                fprintf(pOut,
     396                        "    uint32_t offMsgFull  : 23; /* need %u bits, max %#x */\n"
     397                        "    uint32_t cchMsgFull  :  9; /* need %u bits, max %#x */\n",
     398                        MsgFull.cBitsOffset, MsgFull.offMax, MsgFull.cBitsLength, MsgFull.cchMax);
     399            fprintf(pOut,
     400                    "    int32_t  iCode; /* need %u bits */\n", cBitsCode);
     401        }
     402        fprintf(pOut,
    269403                "} RTMSGENTRYINT;\n"
    270404                "typedef RTMSGENTRYINT *PCRTMSGENTRYINT;\n"
     405                "#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)\n"
     406                "# pragma pack()\n"
     407                "#endif\n"
    271408                "\n"
    272409                "static const RTMSGENTRYINT g_aStatusMsgs[ /*%lu*/ ] =\n"
    273410                "{\n"
    274411                ,
    275                 enmMode != kMode_OnlyDefines
    276                 ? "    uint32_t offMsgShort : 23;\n"
    277                   "    uint32_t cchMsgShort : 9;\n" : "",
    278                 enmMode == kMode_All
    279                 ? "    uint32_t offMsgFull  : 23;\n"
    280                   "    uint32_t cchMsgFull  : 9;\n" : "",
    281412                (unsigned long)cStatusMsgs);
    282413
    283         if (enmMode == kMode_All)
     414        if (enmMode == kMode_All && fOptimalLayout)
    284415            for (size_t i = 0; i < cStatusMsgs; i++)
    285                 fprintf(pOut, "/*%8d:*/ { %#08x, %3u, %#08x, %3u, %#08x, %3u, %s },\n",
     416                fprintf(pOut, "    { %#08x, %#08x, %#08x, %3u, %6d, %3u, %3u }, /* %s */\n",
     417                        s_aStatusMsgs2[i].Define.offStrTab,
     418                        s_aStatusMsgs2[i].MsgShort.offStrTab,
     419                        s_aStatusMsgs2[i].MsgFull.offStrTab,
     420                        (unsigned)s_aStatusMsgs2[i].MsgFull.cchString,
    286421                        s_aStatusMsgs2[i].iCode,
     422                        (unsigned)s_aStatusMsgs2[i].MsgShort.cchString,
     423                        (unsigned)s_aStatusMsgs2[i].Define.cchString,
     424                        s_aStatusMsgs2[i].pszDefine);
     425        else if (enmMode == kMode_All)
     426            for (size_t i = 0; i < cStatusMsgs; i++)
     427                fprintf(pOut, "    { %#08x, %3u, %#08x, %3u, %#08x, %3u, %8d }, /* %s */\n",
    287428                        s_aStatusMsgs2[i].Define.offStrTab,
    288429                        (unsigned)s_aStatusMsgs2[i].Define.cchString,
     
    291432                        s_aStatusMsgs2[i].MsgFull.offStrTab,
    292433                        (unsigned)s_aStatusMsgs2[i].MsgFull.cchString,
     434                        s_aStatusMsgs2[i].iCode,
    293435                        s_aStatusMsgs2[i].pszDefine);
    294436        else if (enmMode == kMode_NoFullMsg)
    295437            for (size_t i = 0; i < cStatusMsgs; i++)
    296                 fprintf(pOut, "/*%8d:*/ { %#08x, %3u, %#08x, %3u, %s },\n",
    297                         s_aStatusMsgs2[i].iCode,
     438                fprintf(pOut, "    { %#08x, %3u, %#08x, %3u, %8d }, /* %s */\n",
    298439                        s_aStatusMsgs2[i].Define.offStrTab,
    299440                        (unsigned)s_aStatusMsgs2[i].Define.cchString,
    300441                        s_aStatusMsgs2[i].MsgShort.offStrTab,
    301442                        (unsigned)s_aStatusMsgs2[i].MsgShort.cchString,
     443                        s_aStatusMsgs2[i].iCode,
    302444                        s_aStatusMsgs2[i].pszDefine);
    303445        else if (enmMode == kMode_OnlyDefines)
    304446            for (size_t i = 0; i < cStatusMsgs; i++)
    305                 fprintf(pOut, "/*%8d:*/ { %#08x, %3u, %s },\n",
    306                         s_aStatusMsgs2[i].iCode,
     447                fprintf(pOut, "    { %#08x, %3u, %8d }, /* %s */\n",
    307448                        s_aStatusMsgs2[i].Define.offStrTab,
    308449                        (unsigned)s_aStatusMsgs2[i].Define.cchString,
     450                        s_aStatusMsgs2[i].iCode,
    309451                        s_aStatusMsgs2[i].pszDefine);
    310452        else
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette