/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * This code generate "register maps" for Dalvik bytecode.  In a stack-based
 * VM we might call these "stack maps".  They are used to increase the
 * precision in the garbage collector when scanning references in the
 * interpreter thread stacks.
 */
#include "Dalvik.h"
#include "UniquePtr.h"
#include "analysis/CodeVerify.h"
#include "analysis/RegisterMap.h"
#include "libdex/DexCatch.h"
#include "libdex/InstrUtils.h"
#include "libdex/Leb128.h"

#include <stddef.h>

/* double-check the compression */
#define REGISTER_MAP_VERIFY     false

/* verbose logging */
#define REGISTER_MAP_VERBOSE    false

//#define REGISTER_MAP_STATS

// fwd
static void outputTypeVector(const RegType* regs, int insnRegCount, u1* data);
static bool verifyMap(VerifierData* vdata, const RegisterMap* pMap);
static int compareMaps(const RegisterMap* pMap1, const RegisterMap* pMap2);

#ifdef REGISTER_MAP_STATS
static void computeMapStats(RegisterMap* pMap, const Method* method);
#endif
static RegisterMap* compressMapDifferential(const RegisterMap* pMap,\
    const Method* meth);
static RegisterMap* uncompressMapDifferential(const RegisterMap* pMap);

#ifdef REGISTER_MAP_STATS
/*
 * Generate some statistics on the register maps we create and use.
 */
#define kMaxGcPointGap      50
#define kUpdatePosnMinRegs  24
#define kNumUpdatePosns     8
#define kMaxDiffBits        20
struct MapStats {
    /*
     * Buckets measuring the distance between GC points.  This tells us how
     * many bits we need to encode the advancing program counter.  We ignore
     * some of the "long tail" entries.
     */
    int gcPointGap[kMaxGcPointGap];

    /*
     * Number of gaps.  Equal to (number of gcPoints - number of methods),
     * since the computation isn't including the initial gap.
     */
    int gcGapCount;

    /*
     * Number of gaps.
     */
    int totalGcPointCount;

    /*
     * For larger methods (>= 24 registers), measure in which octant register
     * updates occur.  This should help us understand whether register
     * changes tend to cluster in the low regs even for large methods.
     */
    int updatePosn[kNumUpdatePosns];

    /*
     * For all methods, count up the number of changes to registers < 16
     * and >= 16.
     */
    int updateLT16;
    int updateGE16;

    /*
     * Histogram of the number of bits that differ between adjacent entries.
     */
    int numDiffBits[kMaxDiffBits];


    /*
     * Track the number of expanded maps, and the heap space required to
     * hold them.
     */
    int numExpandedMaps;
    int totalExpandedMapSize;
};
#endif

/*
 * Prepare some things.
 */
bool dvmRegisterMapStartup()
{
#ifdef REGISTER_MAP_STATS
    MapStats* pStats = calloc(1, sizeof(MapStats));
    gDvm.registerMapStats = pStats;
#endif
    return true;
}

/*
 * Clean up.
 */
void dvmRegisterMapShutdown()
{
#ifdef REGISTER_MAP_STATS
    free(gDvm.registerMapStats);
#endif
}

/*
 * Write stats to log file.
 */
void dvmRegisterMapDumpStats()
{
#ifdef REGISTER_MAP_STATS
    MapStats* pStats = (MapStats*) gDvm.registerMapStats;
    int i, end;

    for (end = kMaxGcPointGap-1; end >= 0; end--) {
        if (pStats->gcPointGap[end] != 0)
            break;
    }

    LOGI("Register Map gcPointGap stats (diff count=%d, total=%d):",
        pStats->gcGapCount, pStats->totalGcPointCount);
    assert(pStats->gcPointGap[0] == 0);
    for (i = 1; i <= end; i++) {
        LOGI(" %2d %d", i, pStats->gcPointGap[i]);
    }


    for (end = kMaxDiffBits-1; end >= 0; end--) {
        if (pStats->numDiffBits[end] != 0)
            break;
    }

    LOGI("Register Map bit difference stats:");
    for (i = 0; i <= end; i++) {
        LOGI(" %2d %d", i, pStats->numDiffBits[i]);
    }


    LOGI("Register Map update position stats (lt16=%d ge16=%d):",
        pStats->updateLT16, pStats->updateGE16);
    for (i = 0; i < kNumUpdatePosns; i++) {
        LOGI(" %2d %d", i, pStats->updatePosn[i]);
    }
#endif
}


/*
 * ===========================================================================
 *      Map generation
 * ===========================================================================
 */

/*
 * Generate the register map for a method that has just been verified
 * (i.e. we're doing this as part of verification).
 *
 * For type-precise determination we have all the data we need, so we
 * just need to encode it in some clever fashion.
 *
 * Returns a pointer to a newly-allocated RegisterMap, or NULL on failure.
 */
RegisterMap* dvmGenerateRegisterMapV(VerifierData* vdata)
{
    static const int kHeaderSize = offsetof(RegisterMap, data);
    RegisterMap* pMap = NULL;
    RegisterMap* pResult = NULL;
    RegisterMapFormat format;
    u1 regWidth;
    u1* mapData;
    int i, bytesForAddr, gcPointCount;
    int bufSize;

    if (vdata->method->registersSize >= 2048) {
        LOGE("ERROR: register map can't handle %d registers",
            vdata->method->registersSize);
        goto bail;
    }
    regWidth = (vdata->method->registersSize + 7) / 8;

    /*
     * Decide if we need 8 or 16 bits to hold the address.  Strictly speaking
     * we only need 16 bits if we actually encode an address >= 256 -- if
     * the method has a section at the end without GC points (e.g. array
     * data) we don't need to count it.  The situation is unusual, and
     * detecting it requires scanning the entire method, so we don't bother.
     */
    if (vdata->insnsSize < 256) {
        format = kRegMapFormatCompact8;
        bytesForAddr = 1;
    } else {
        format = kRegMapFormatCompact16;
        bytesForAddr = 2;
    }

    /*
     * Count up the number of GC point instructions.
     *
     * NOTE: this does not automatically include the first instruction,
     * since we don't count method entry as a GC point.
     */
    gcPointCount = 0;
    for (i = 0; i < (int) vdata->insnsSize; i++) {
        if (dvmInsnIsGcPoint(vdata->insnFlags, i))
            gcPointCount++;
    }
    if (gcPointCount >= 65536) {
        /* we could handle this, but in practice we don't get near this */
        LOGE("ERROR: register map can't handle %d gc points in one method",
            gcPointCount);
        goto bail;
    }

    /*
     * Allocate a buffer to hold the map data.
     */
    bufSize = kHeaderSize + gcPointCount * (bytesForAddr + regWidth);

    LOGV("+++ grm: %s.%s (adr=%d gpc=%d rwd=%d bsz=%d)",
        vdata->method->clazz->descriptor, vdata->method->name,
        bytesForAddr, gcPointCount, regWidth, bufSize);

    pMap = (RegisterMap*) malloc(bufSize);
    dvmRegisterMapSetFormat(pMap, format);
    dvmRegisterMapSetOnHeap(pMap, true);
    dvmRegisterMapSetRegWidth(pMap, regWidth);
    dvmRegisterMapSetNumEntries(pMap, gcPointCount);

    /*
     * Populate it.
     */
    mapData = pMap->data;
    for (i = 0; i < (int) vdata->insnsSize; i++) {
        if (dvmInsnIsGcPoint(vdata->insnFlags, i)) {
            assert(vdata->registerLines[i].regTypes != NULL);
            if (format == kRegMapFormatCompact8) {
                *mapData++ = i;
            } else /*kRegMapFormatCompact16*/ {
                *mapData++ = i & 0xff;
                *mapData++ = i >> 8;
            }
            outputTypeVector(vdata->registerLines[i].regTypes,
                vdata->insnRegCount, mapData);
            mapData += regWidth;
        }
    }

    LOGV("mapData=%p pMap=%p bufSize=%d", mapData, pMap, bufSize);
    assert(mapData - (const u1*) pMap == bufSize);

    if (REGISTER_MAP_VERIFY && !verifyMap(vdata, pMap))
        goto bail;
#ifdef REGISTER_MAP_STATS
    computeMapStats(pMap, vdata->method);
#endif

    /*
     * Try to compress the map.
     */
    RegisterMap* pCompMap;

    pCompMap = compressMapDifferential(pMap, vdata->method);
    if (pCompMap != NULL) {
        if (REGISTER_MAP_VERIFY) {
            /*
             * Expand the compressed map we just created, and compare it
             * to the original.  Abort the VM if it doesn't match up.
             */
            RegisterMap* pUncompMap;
            pUncompMap = uncompressMapDifferential(pCompMap);
            if (pUncompMap == NULL) {
                LOGE("Map failed to uncompress - %s.%s",
                    vdata->method->clazz->descriptor,
                    vdata->method->name);
                free(pCompMap);
                /* bad - compression is broken or we're out of memory */
                dvmAbort();
            } else {
                if (compareMaps(pMap, pUncompMap) != 0) {
                    LOGE("Map comparison failed - %s.%s",
                        vdata->method->clazz->descriptor,
                        vdata->method->name);
                    free(pCompMap);
                    /* bad - compression is broken */
                    dvmAbort();
                }

                /* verify succeeded */
                delete pUncompMap;
            }
        }

        if (REGISTER_MAP_VERBOSE) {
            LOGD("Good compress on %s.%s",
                vdata->method->clazz->descriptor,
                vdata->method->name);
        }
        free(pMap);
        pMap = pCompMap;
    } else {
        if (REGISTER_MAP_VERBOSE) {
            LOGD("Unable to compress %s.%s (ent=%d rw=%d)",
                vdata->method->clazz->descriptor,
                vdata->method->name,
                dvmRegisterMapGetNumEntries(pMap),
                dvmRegisterMapGetRegWidth(pMap));
        }
    }

    pResult = pMap;

bail:
    return pResult;
}

/*
 * Release the storage held by a RegisterMap.
 */
void dvmFreeRegisterMap(RegisterMap* pMap)
{
    if (pMap == NULL)
        return;

    assert(dvmRegisterMapGetOnHeap(pMap));
    free(pMap);
}

/*
 * Determine if the RegType value is a reference type.
 *
 * Ordinarily we include kRegTypeZero in the "is it a reference"
 * check.  There's no value in doing so here, because we know
 * the register can't hold anything but zero.
 */
static inline bool isReferenceType(RegType type)
{
    return (type > kRegTypeMAX || type == kRegTypeUninit);
}

/*
 * Given a line of registers, output a bit vector that indicates whether
 * or not the register holds a reference type (which could be null).
 *
 * We use '1' to indicate it's a reference, '0' for anything else (numeric
 * value, uninitialized data, merge conflict).  Register 0 will be found
 * in the low bit of the first byte.
 */
static void outputTypeVector(const RegType* regs, int insnRegCount, u1* data)
{
    u1 val = 0;
    int i;

    for (i = 0; i < insnRegCount; i++) {
        RegType type = *regs++;
        val >>= 1;
        if (isReferenceType(type))
            val |= 0x80;        /* set hi bit */

        if ((i & 0x07) == 7)
            *data++ = val;
    }
    if ((i & 0x07) != 0) {
        /* flush bits from last byte */
        val >>= 8 - (i & 0x07);
        *data++ = val;
    }
}

/*
 * Print the map as a series of binary strings.
 *
 * Pass in method->registersSize if known, or -1 if not.
 */
static void dumpRegisterMap(const RegisterMap* pMap, int registersSize)
{
    const u1* rawMap = pMap->data;
    const RegisterMapFormat format = dvmRegisterMapGetFormat(pMap);
    const int numEntries = dvmRegisterMapGetNumEntries(pMap);
    const int regWidth = dvmRegisterMapGetRegWidth(pMap);
    int addrWidth;

    switch (format) {
    case kRegMapFormatCompact8:
        addrWidth = 1;
        break;
    case kRegMapFormatCompact16:
        addrWidth = 2;
        break;
    default:
        /* can't happen */
        LOGE("Can only dump Compact8 / Compact16 maps (not %d)", format);
        return;
    }

    if (registersSize < 0)
        registersSize = 8 * regWidth;
    assert(registersSize <= regWidth * 8);

    int ent;
    for (ent = 0; ent < numEntries; ent++) {
        int i, addr;

        addr = *rawMap++;
        if (addrWidth > 1)
            addr |= (*rawMap++) << 8;

        const u1* dataStart = rawMap;
        u1 val = 0;

        /* create binary string */
        char outBuf[registersSize +1];
        for (i = 0; i < registersSize; i++) {
            val >>= 1;
            if ((i & 0x07) == 0)
                val = *rawMap++;

            outBuf[i] = '0' + (val & 0x01);
        }
        outBuf[i] = '\0';

        /* back up and create hex dump */
        char hexBuf[regWidth * 3 +1];
        char* cp = hexBuf;
        rawMap = dataStart;
        for (i = 0; i < regWidth; i++) {
            sprintf(cp, " %02x", *rawMap++);
            cp += 3;
        }
        hexBuf[i * 3] = '\0';

        LOGD("  %04x %s %s", addr, outBuf, hexBuf);
    }
}

/*
 * Double-check the map.
 *
 * We run through all of the data in the map, and compare it to the original.
 * Only works on uncompressed data.
 */
static bool verifyMap(VerifierData* vdata, const RegisterMap* pMap)
{
    const u1* rawMap = pMap->data;
    const RegisterMapFormat format = dvmRegisterMapGetFormat(pMap);
    const int numEntries = dvmRegisterMapGetNumEntries(pMap);
    int ent;
    bool dumpMap = false;

    if (false) {
        const char* cd = "Landroid/net/http/Request;";
        const char* mn = "readResponse";
        if (strcmp(vdata->method->clazz->descriptor, cd) == 0 &&
            strcmp(vdata->method->name, mn) == 0)
        {
            char* desc;
            desc = dexProtoCopyMethodDescriptor(&vdata->method->prototype);
            LOGI("Map for %s.%s %s", vdata->method->clazz->descriptor,
                vdata->method->name, desc);
            free(desc);

            dumpMap = true;
        }
    }

    if ((vdata->method->registersSize + 7) / 8 != pMap->regWidth) {
        LOGE("GLITCH: registersSize=%d, regWidth=%d",
            vdata->method->registersSize, pMap->regWidth);
        return false;
    }

    for (ent = 0; ent < numEntries; ent++) {
        int addr;

        switch (format) {
        case kRegMapFormatCompact8:
            addr = *rawMap++;
            break;
        case kRegMapFormatCompact16:
            addr = *rawMap++;
            addr |= (*rawMap++) << 8;
            break;
        default:
            /* shouldn't happen */
            LOGE("GLITCH: bad format (%d)", format);
            dvmAbort();
        }

        const RegType* regs = vdata->registerLines[addr].regTypes;
        if (regs == NULL) {
            LOGE("GLITCH: addr %d has no data", addr);
            return false;
        }

        u1 val = 0;
        int i;

        for (i = 0; i < vdata->method->registersSize; i++) {
            bool bitIsRef, regIsRef;

            val >>= 1;
            if ((i & 0x07) == 0) {
                /* load next byte of data */
                val = *rawMap++;
            }

            bitIsRef = val & 0x01;

            RegType type = regs[i];
            regIsRef = isReferenceType(type);

            if (bitIsRef != regIsRef) {
                LOGE("GLITCH: addr %d reg %d: bit=%d reg=%d(%d)",
                    addr, i, bitIsRef, regIsRef, type);
                return false;
            }
        }

        /* rawMap now points to the address field of the next entry */
    }

    if (dumpMap)
        dumpRegisterMap(pMap, vdata->method->registersSize);

    return true;
}


/*
 * ===========================================================================
 *      DEX generation & parsing
 * ===========================================================================
 */

/*
 * Advance "ptr" to ensure 32-bit alignment.
 */
static inline u1* align32(u1* ptr)
{
    return (u1*) (((int) ptr + 3) & ~0x03);
}

/*
 * Compute the size, in bytes, of a register map.
 */
static size_t computeRegisterMapSize(const RegisterMap* pMap)
{
    static const int kHeaderSize = offsetof(RegisterMap, data);
    u1 format = dvmRegisterMapGetFormat(pMap);
    u2 numEntries = dvmRegisterMapGetNumEntries(pMap);

    assert(pMap != NULL);

    switch (format) {
    case kRegMapFormatNone:
        return 1;
    case kRegMapFormatCompact8:
        return kHeaderSize + (1 + pMap->regWidth) * numEntries;
    case kRegMapFormatCompact16:
        return kHeaderSize + (2 + pMap->regWidth) * numEntries;
    case kRegMapFormatDifferential:
        {
            /* kHeaderSize + decoded ULEB128 length */
            const u1* ptr = pMap->data;
            int len = readUnsignedLeb128(&ptr);
            return len + (ptr - (u1*) pMap);
        }
    default:
        LOGE("Bad register map format %d", format);
        dvmAbort();
        return 0;
    }
}

/*
 * Output the map for a single method, if it has one.
 *
 * Abstract and native methods have no map.  All others are expected to
 * have one, since we know the class verified successfully.
 *
 * This strips the "allocated on heap" flag from the format byte, so that
 * direct-mapped maps are correctly identified as such.
 */
static bool writeMapForMethod(const Method* meth, u1** pPtr)
{
    if (meth->registerMap == NULL) {
        if (!dvmIsAbstractMethod(meth) && !dvmIsNativeMethod(meth)) {
            LOGW("Warning: no map available for %s.%s",
                meth->clazz->descriptor, meth->name);
            /* weird, but keep going */
        }
        *(*pPtr)++ = kRegMapFormatNone;
        return true;
    }

    /* serialize map into the buffer */
    size_t mapSize = computeRegisterMapSize(meth->registerMap);
    memcpy(*pPtr, meth->registerMap, mapSize);

    /* strip the "on heap" flag out of the format byte, which is always first */
    assert(**pPtr == meth->registerMap->format);
    **pPtr &= ~(kRegMapFormatOnHeap);

    *pPtr += mapSize;

    return true;
}

/*
 * Write maps for all methods in the specified class to the buffer, which
 * can hold at most "length" bytes.  "*pPtr" will be advanced past the end
 * of the data we write.
 */
static bool writeMapsAllMethods(DvmDex* pDvmDex, const ClassObject* clazz,
    u1** pPtr, size_t length)
{
    RegisterMapMethodPool* pMethodPool;
    u1* ptr = *pPtr;
    int i, methodCount;

    /* artificial limit */
    if (clazz->virtualMethodCount + clazz->directMethodCount >= 65536) {
        LOGE("Too many methods in %s", clazz->descriptor);
        return false;
    }

    pMethodPool = (RegisterMapMethodPool*) ptr;
    ptr += offsetof(RegisterMapMethodPool, methodData);
    methodCount = 0;

    /*
     * Run through all methods, direct then virtual.  The class loader will
     * traverse them in the same order.  (We could split them into two
     * distinct pieces, but there doesn't appear to be any value in doing
     * so other than that it makes class loading slightly less fragile.)
     *
     * The class loader won't know about miranda methods at the point
     * where it parses this, so we omit those.
     *
     * TODO: consider omitting all native/abstract definitions.  Should be
     * safe, though we lose the ability to sanity-check against the
     * method counts in the DEX file.
     */
    for (i = 0; i < clazz->directMethodCount; i++) {
        const Method* meth = &clazz->directMethods[i];
        if (dvmIsMirandaMethod(meth))
            continue;
        if (!writeMapForMethod(&clazz->directMethods[i], &ptr)) {
            return false;
        }
        methodCount++;
        //ptr = align32(ptr);
    }

    for (i = 0; i < clazz->virtualMethodCount; i++) {
        const Method* meth = &clazz->virtualMethods[i];
        if (dvmIsMirandaMethod(meth))
            continue;
        if (!writeMapForMethod(&clazz->virtualMethods[i], &ptr)) {
            return false;
        }
        methodCount++;
        //ptr = align32(ptr);
    }

    pMethodPool->methodCount = methodCount;

    *pPtr = ptr;
    return true;
}

/*
 * Write maps for all classes to the specified buffer, which can hold at
 * most "length" bytes.
 *
 * Returns the actual length used, or 0 on failure.
 */
static size_t writeMapsAllClasses(DvmDex* pDvmDex, u1* basePtr, size_t length)
{
    DexFile* pDexFile = pDvmDex->pDexFile;
    u4 count = pDexFile->pHeader->classDefsSize;
    RegisterMapClassPool* pClassPool;
    u4* offsetTable;
    u1* ptr = basePtr;
    u4 idx;

    assert(gDvm.optimizing);

    pClassPool = (RegisterMapClassPool*) ptr;
    ptr += offsetof(RegisterMapClassPool, classDataOffset);
    offsetTable = (u4*) ptr;
    ptr += count * sizeof(u4);

    pClassPool->numClasses = count;

    /*
     * We want an entry for every class, loaded or not.
     */
    for (idx = 0; idx < count; idx++) {
        const DexClassDef* pClassDef;
        const char* classDescriptor;
        ClassObject* clazz;

        pClassDef = dexGetClassDef(pDexFile, idx);
        classDescriptor = dexStringByTypeIdx(pDexFile, pClassDef->classIdx);

        /*
         * All classes have been loaded into the bootstrap class loader.
         * If we can find it, and it was successfully pre-verified, we
         * run through its methods and add the register maps.
         *
         * If it wasn't pre-verified then we know it can't have any
         * register maps.  Classes that can't be loaded or failed
         * verification get an empty slot in the index.
         */
        clazz = NULL;
        if ((pClassDef->accessFlags & CLASS_ISPREVERIFIED) != 0)
            clazz = dvmLookupClass(classDescriptor, NULL, false);

        if (clazz != NULL) {
            offsetTable[idx] = ptr - basePtr;
            LOGVV("%d -> offset %d (%p-%p)",
                idx, offsetTable[idx], ptr, basePtr);

            if (!writeMapsAllMethods(pDvmDex, clazz, &ptr,
                    length - (ptr - basePtr)))
            {
                return 0;
            }

            ptr = align32(ptr);
            LOGVV("Size %s (%d+%d methods): %d", clazz->descriptor,
                clazz->directMethodCount, clazz->virtualMethodCount,
                (ptr - basePtr) - offsetTable[idx]);
        } else {
            LOGV("%4d NOT mapadding '%s'", idx, classDescriptor);
            assert(offsetTable[idx] == 0);
        }
    }

    if (ptr - basePtr >= (int)length) {
        /* a bit late */
        LOGE("Buffer overrun");
        dvmAbort();
    }

    return ptr - basePtr;
}

/*
 * Generate a register map set for all verified classes in "pDvmDex".
 */
RegisterMapBuilder* dvmGenerateRegisterMaps(DvmDex* pDvmDex)
{
    RegisterMapBuilder* pBuilder;

    pBuilder = (RegisterMapBuilder*) calloc(1, sizeof(RegisterMapBuilder));
    if (pBuilder == NULL)
        return NULL;

    /*
     * We have a couple of options here:
     *  (1) Compute the size of the output, and malloc a buffer.
     *  (2) Create a "large-enough" anonymous mmap region.
     *
     * The nice thing about option #2 is that we don't have to traverse
     * all of the classes and methods twice.  The risk is that we might
     * not make the region large enough.  Since the pages aren't mapped
     * until used we can allocate a semi-absurd amount of memory without
     * worrying about the effect on the rest of the system.
     *
     * The basic encoding on the largest jar file requires about 1MB of
     * storage.  We map out 4MB here.  (TODO: guarantee that the last
     * page of the mapping is marked invalid, so we reliably fail if
     * we overrun.)
     */
    if (sysCreatePrivateMap(4 * 1024 * 1024, &pBuilder->memMap) != 0) {
        free(pBuilder);
        return NULL;
    }

    /*
     * Create the maps.
     */
    size_t actual = writeMapsAllClasses(pDvmDex, (u1*)pBuilder->memMap.addr,
                                        pBuilder->memMap.length);
    if (actual == 0) {
        dvmFreeRegisterMapBuilder(pBuilder);
        return NULL;
    }

    LOGV("TOTAL size of register maps: %d", actual);

    pBuilder->data = pBuilder->memMap.addr;
    pBuilder->size = actual;
    return pBuilder;
}

/*
 * Free the builder.
 */
void dvmFreeRegisterMapBuilder(RegisterMapBuilder* pBuilder)
{
    if (pBuilder == NULL)
        return;

    sysReleaseShmem(&pBuilder->memMap);
    free(pBuilder);
}


/*
 * Find the data for the specified class.
 *
 * If there's no register map data, or none for this class, we return NULL.
 */
const void* dvmRegisterMapGetClassData(const DexFile* pDexFile, u4 classIdx,
    u4* pNumMaps)
{
    const RegisterMapClassPool* pClassPool;
    const RegisterMapMethodPool* pMethodPool;

    pClassPool = (const RegisterMapClassPool*) pDexFile->pRegisterMapPool;
    if (pClassPool == NULL)
        return NULL;

    if (classIdx >= pClassPool->numClasses) {
        LOGE("bad class index (%d vs %d)", classIdx, pClassPool->numClasses);
        dvmAbort();
    }

    u4 classOffset = pClassPool->classDataOffset[classIdx];
    if (classOffset == 0) {
        LOGV("+++ no map for classIdx=%d", classIdx);
        return NULL;
    }

    pMethodPool =
        (const RegisterMapMethodPool*) (((u1*) pClassPool) + classOffset);
    if (pNumMaps != NULL)
        *pNumMaps = pMethodPool->methodCount;
    return pMethodPool->methodData;
}

/*
 * This advances "*pPtr" and returns its original value.
 */
const RegisterMap* dvmRegisterMapGetNext(const void** pPtr)
{
    const RegisterMap* pMap = (const RegisterMap*) *pPtr;

    *pPtr = /*align32*/(((u1*) pMap) + computeRegisterMapSize(pMap));
    LOGVV("getNext: %p -> %p (f=%#x w=%d e=%d)",
        pMap, *pPtr, pMap->format, pMap->regWidth,
        dvmRegisterMapGetNumEntries(pMap));
    return pMap;
}


/*
 * ===========================================================================
 *      Utility functions
 * ===========================================================================
 */

/*
 * Return the data for the specified address, or NULL if not found.
 *
 * The result must be released with dvmReleaseRegisterMapLine().
 */
const u1* dvmRegisterMapGetLine(const RegisterMap* pMap, int addr)
{
    int addrWidth, lineWidth;
    u1 format = dvmRegisterMapGetFormat(pMap);
    u2 numEntries = dvmRegisterMapGetNumEntries(pMap);

    assert(numEntries > 0);

    switch (format) {
    case kRegMapFormatNone:
        return NULL;
    case kRegMapFormatCompact8:
        addrWidth = 1;
        break;
    case kRegMapFormatCompact16:
        addrWidth = 2;
        break;
    default:
        LOGE("Unknown format %d", format);
        dvmAbort();
        return NULL;
    }

    lineWidth = addrWidth + pMap->regWidth;

    /*
     * Find the appropriate entry.  Many maps are very small, some are very
     * large.
     */
    static const int kSearchThreshold = 8;
    const u1* data = NULL;
    int lineAddr;

    if (numEntries < kSearchThreshold) {
        int i;
        data = pMap->data;
        for (i = numEntries; i > 0; i--) {
            lineAddr = data[0];
            if (addrWidth > 1)
                lineAddr |= data[1] << 8;
            if (lineAddr == addr)
                return data + addrWidth;

            data += lineWidth;
        }
        assert(data == pMap->data + lineWidth * numEntries);
    } else {
        int hi, lo, mid;

        lo = 0;
        hi = numEntries -1;

        while (hi >= lo) {
            mid = (hi + lo) / 2;
            data = pMap->data + lineWidth * mid;

            lineAddr = data[0];
            if (addrWidth > 1)
                lineAddr |= data[1] << 8;

            if (addr > lineAddr) {
                lo = mid + 1;
            } else if (addr < lineAddr) {
                hi = mid - 1;
            } else {
                return data + addrWidth;
            }
        }
    }

    return NULL;
}

/*
 * Compare two register maps.
 *
 * Returns 0 if they're equal, nonzero if not.
 */
static int compareMaps(const RegisterMap* pMap1, const RegisterMap* pMap2)
{
    size_t size1, size2;

    size1 = computeRegisterMapSize(pMap1);
    size2 = computeRegisterMapSize(pMap2);
    if (size1 != size2) {
        LOGI("compareMaps: size mismatch (%zd vs %zd)", size1, size2);
        return -1;
    }

    if (memcmp(pMap1, pMap2, size1) != 0) {
        LOGI("compareMaps: content mismatch");
        return -1;
    }

    return 0;
}


/*
 * Get the expanded form of the register map associated with the method.
 *
 * If the map is already in one of the uncompressed formats, we return
 * immediately.  Otherwise, we expand the map and replace method's register
 * map pointer, freeing it if it was allocated on the heap.
 *
 * NOTE: this function is not synchronized; external locking is mandatory
 * (unless we're in the zygote, where single-threaded access is guaranteed).
 */
const RegisterMap* dvmGetExpandedRegisterMap0(Method* method)
{
    const RegisterMap* curMap = method->registerMap;
    RegisterMap* newMap;

    if (curMap == NULL)
        return NULL;

    /* sanity check to ensure this isn't called w/o external locking */
    /* (if we use this at a time other than during GC, fix/remove this test) */
    if (true) {
        if (!gDvm.zygote && dvmTryLockMutex(&gDvm.gcHeapLock) == 0) {
            LOGE("GLITCH: dvmGetExpandedRegisterMap not called at GC time");
            dvmAbort();
        }
    }

    RegisterMapFormat format = dvmRegisterMapGetFormat(curMap);
    switch (format) {
    case kRegMapFormatCompact8:
    case kRegMapFormatCompact16:
        if (REGISTER_MAP_VERBOSE) {
            if (dvmRegisterMapGetOnHeap(curMap)) {
                LOGD("RegMap: already expanded: %s.%s",
                    method->clazz->descriptor, method->name);
            } else {
                LOGD("RegMap: stored w/o compression: %s.%s",
                    method->clazz->descriptor, method->name);
            }
        }
        return curMap;
    case kRegMapFormatDifferential:
        newMap = uncompressMapDifferential(curMap);
        break;
    default:
        LOGE("Unknown format %d in dvmGetExpandedRegisterMap", format);
        dvmAbort();
        newMap = NULL;      // make gcc happy
    }

    if (newMap == NULL) {
        LOGE("Map failed to uncompress (fmt=%d) %s.%s",
            format, method->clazz->descriptor, method->name);
        return NULL;
    }

#ifdef REGISTER_MAP_STATS
    /*
     * Gather and display some stats.
     */
    {
        MapStats* pStats = (MapStats*) gDvm.registerMapStats;
        pStats->numExpandedMaps++;
        pStats->totalExpandedMapSize += computeRegisterMapSize(newMap);
        LOGD("RMAP: count=%d size=%d",
            pStats->numExpandedMaps, pStats->totalExpandedMapSize);
    }
#endif

    IF_LOGV() {
        char* desc = dexProtoCopyMethodDescriptor(&method->prototype);
        LOGV("Expanding map -> %s.%s:%s",
            method->clazz->descriptor, method->name, desc);
        free(desc);
    }

    /*
     * Update method, and free compressed map if it was sitting on the heap.
     */
    dvmSetRegisterMap(method, newMap);

    if (dvmRegisterMapGetOnHeap(curMap))
        dvmFreeRegisterMap((RegisterMap*) curMap);

    return newMap;
}


/*
 * ===========================================================================
 *      Map compression
 * ===========================================================================
 */

/*
Notes on map compression

The idea is to create a compressed form that will be uncompressed before
use, with the output possibly saved in a cache.  This means we can use an
approach that is unsuited for random access if we choose.

In the event that a map simply does not work with our compression scheme,
it's reasonable to store the map without compression.  In the future we
may want to have more than one compression scheme, and try each in turn,
retaining the best.  (We certainly want to keep the uncompressed form if it
turns out to be smaller or even slightly larger than the compressed form.)

Each entry consists of an address and a bit vector.  Adjacent entries are
strongly correlated, suggesting differential encoding.


Ideally we would avoid outputting adjacent entries with identical
bit vectors.  However, the register values at a given address do not
imply anything about the set of valid registers at subsequent addresses.
We therefore cannot omit an entry.

  If the thread stack has a PC at an address without a corresponding
  entry in the register map, we must conservatively scan the registers in
  that thread.  This can happen when single-stepping in the debugger,
  because the debugger is allowed to invoke arbitrary methods when
  a thread is stopped at a breakpoint.  If we can guarantee that a GC
  thread scan will never happen while the debugger has that thread stopped,
  then we can lift this restriction and simply omit entries that don't
  change the bit vector from its previous state.

Each entry advances the address value by at least 1 (measured in 16-bit
"code units").  Looking at the bootclasspath entries, advancing by 2 units
is most common.  Advances by 1 unit are far less common than advances by
2 units, but more common than 5, and things fall off rapidly.  Gaps of
up to 220 code units appear in some computationally intensive bits of code,
but are exceedingly rare.

If we sum up the number of transitions in a couple of ranges in framework.jar:
  [1,4]: 188998 of 218922 gaps (86.3%)
  [1,7]: 211647 of 218922 gaps (96.7%)
Using a 3-bit delta, with one value reserved as an escape code, should
yield good results for the address.

These results would change dramatically if we reduced the set of GC
points by e.g. removing instructions like integer divide that are only
present because they can throw and cause an allocation.

We also need to include an "initial gap", because the first few instructions
in a method may not be GC points.


By observation, many entries simply repeat the previous bit vector, or
change only one or two bits.  (This is with type-precise information;
the rate of change of bits will be different if live-precise information
is factored in).

Looking again at adjacent entries in framework.jar:
  0 bits changed: 63.0%
  1 bit changed: 32.2%
After that it falls off rapidly, e.g. the number of entries with 2 bits
changed is usually less than 1/10th of the number of entries with 1 bit
changed.  A solution that allows us to encode 0- or 1- bit changes
efficiently will do well.

We still need to handle cases where a large number of bits change.  We
probably want a way to drop in a full copy of the bit vector when it's
smaller than the representation of multiple bit changes.


The bit-change information can be encoded as an index that tells the
decoder to toggle the state.  We want to encode the index in as few bits
as possible, but we need to allow for fairly wide vectors (e.g. we have a
method with 175 registers).  We can deal with this in a couple of ways:
(1) use an encoding that assumes few registers and has an escape code
for larger numbers of registers; or (2) use different encodings based
on how many total registers the method has.  The choice depends to some
extent on whether methods with large numbers of registers tend to modify
the first 16 regs more often than the others.

The last N registers hold method arguments.  If the bytecode is expected
to be examined in a debugger, "dx" ensures that the contents of these
registers won't change.  Depending upon the encoding format, we may be
able to take advantage of this.  We still have to encode the initial
state, but we know we'll never have to output a bit change for the last
N registers.

Considering only methods with 16 or more registers, the "target octant"
for register changes looks like this:
  [ 43.1%, 16.4%, 6.5%, 6.2%, 7.4%, 8.8%, 9.7%, 1.8% ]
As expected, there are fewer changes at the end of the list where the
arguments are kept, and more changes at the start of the list because
register values smaller than 16 can be used in compact Dalvik instructions
and hence are favored for frequently-used values.  In general, the first
octant is considerably more active than later entries, the last octant
is much less active, and the rest are all about the same.

Looking at all bit changes in all methods, 94% are to registers 0-15.  The
encoding will benefit greatly by favoring the low-numbered registers.


Some of the smaller methods have identical maps, and space could be
saved by simply including a pointer to an earlier definition.  This would
be best accomplished by specifying a "pointer" format value, followed by
a 3-byte (or ULEB128) offset.  Implementing this would probably involve
generating a hash value for each register map and maintaining a hash table.

In some cases there are repeating patterns in the bit vector that aren't
adjacent.  These could benefit from a dictionary encoding.  This doesn't
really become useful until the methods reach a certain size though,
and managing the dictionary may incur more overhead than we want.

Large maps can be compressed significantly.  The trouble is that, when
we need to use them, we have to uncompress them onto the heap.  We may
get a better trade-off between storage size and heap usage by refusing to
compress large maps, so that they can be memory mapped and used directly.
(OTOH, only about 2% of the maps will ever actually be used.)


----- differential format -----

// common header
+00 1B format
+01 1B regWidth
+02 2B numEntries (little-endian)
+04 nB length in bytes of the data that follows, in ULEB128 format
       (not strictly necessary; allows determination of size w/o full parse)
+05+ 1B initial address (0-127), high bit set if max addr >= 256
+06+ nB initial value for bit vector

// for each entry
+00: CCCCBAAA

  AAA: address difference.  Values from 0 to 6 indicate an increment of 1
  to 7.  A value of 7 indicates that the address difference is large,
  and the next byte is a ULEB128-encoded difference value.

  B: determines the meaning of CCCC.

  CCCC: if B is 0, this is the number of the bit to toggle (0-15).
  If B is 1, this is a count of the number of changed bits (1-14).  A value
  of 0 means that no bits were changed, and a value of 15 indicates
  that enough bits were changed that it required less space to output
  the entire bit vector.

+01: (optional) ULEB128-encoded address difference

+01+: (optional) one or more ULEB128-encoded bit numbers, OR the entire
  bit vector.

The most common situation is an entry whose address has changed by 2-4
code units, has no changes or just a single bit change, and the changed
register is less than 16.  We should therefore be able to encode a large
number of entries with a single byte, which is half the size of the
Compact8 encoding method.
*/

/*
 * Compute some stats on an uncompressed register map.
 */
#ifdef REGISTER_MAP_STATS
static void computeMapStats(RegisterMap* pMap, const Method* method)
{
    MapStats* pStats = (MapStats*) gDvm.registerMapStats;
    const u1 format = dvmRegisterMapGetFormat(pMap);
    const u2 numEntries = dvmRegisterMapGetNumEntries(pMap);
    const u1* rawMap = pMap->data;
    const u1* prevData = NULL;
    int ent, addr, prevAddr = -1;

    for (ent = 0; ent < numEntries; ent++) {
        switch (format) {
        case kRegMapFormatCompact8:
            addr = *rawMap++;
            break;
        case kRegMapFormatCompact16:
            addr = *rawMap++;
            addr |= (*rawMap++) << 8;
            break;
        default:
            /* shouldn't happen */
            LOGE("GLITCH: bad format (%d)", format);
            dvmAbort();
        }

        const u1* dataStart = rawMap;

        pStats->totalGcPointCount++;

        /*
         * Gather "gap size" stats, i.e. the difference in addresses between
         * successive GC points.
         */
        if (prevData != NULL) {
            assert(prevAddr >= 0);
            int addrDiff = addr - prevAddr;

            if (addrDiff < 0) {
                LOGE("GLITCH: address went backward (0x%04x->0x%04x, %s.%s)",
                    prevAddr, addr, method->clazz->descriptor, method->name);
            } else if (addrDiff > kMaxGcPointGap) {
                if (REGISTER_MAP_VERBOSE) {
                    LOGI("HEY: addrDiff is %d, max %d (0x%04x->0x%04x %s.%s)",
                        addrDiff, kMaxGcPointGap, prevAddr, addr,
                        method->clazz->descriptor, method->name);
                }
                /* skip this one */
            } else {
                pStats->gcPointGap[addrDiff]++;
            }
            pStats->gcGapCount++;


            /*
             * Compare bit vectors in adjacent entries.  We want to count
             * up the number of bits that differ (to see if we frequently
             * change 0 or 1 bits) and get a sense for which part of the
             * vector changes the most often (near the start, middle, end).
             *
             * We only do the vector position quantization if we have at
             * least 16 registers in the method.
             */
            int numDiff = 0;
            float div = (float) kNumUpdatePosns / method->registersSize;
            int regByte;
            for (regByte = 0; regByte < pMap->regWidth; regByte++) {
                int prev, cur, bit;

                prev = prevData[regByte];
                cur = dataStart[regByte];

                for (bit = 0; bit < 8; bit++) {
                    if (((prev >> bit) & 1) != ((cur >> bit) & 1)) {
                        numDiff++;

                        int bitNum = regByte * 8 + bit;

                        if (bitNum < 16)
                            pStats->updateLT16++;
                        else
                            pStats->updateGE16++;

                        if (method->registersSize < 16)
                            continue;

                        if (bitNum >= method->registersSize) {
                            /* stuff off the end should be zero in both */
                            LOGE("WEIRD: bit=%d (%d/%d), prev=%02x cur=%02x",
                                bit, regByte, method->registersSize,
                                prev, cur);
                            assert(false);
                        }
                        int idx = (int) (bitNum * div);
                        if (!(idx >= 0 && idx < kNumUpdatePosns)) {
                            LOGE("FAIL: bitNum=%d (of %d) div=%.3f idx=%d",
                                bitNum, method->registersSize, div, idx);
                            assert(false);
                        }
                        pStats->updatePosn[idx]++;
                    }
                }
            }

            if (numDiff > kMaxDiffBits) {
                if (REGISTER_MAP_VERBOSE) {
                    LOGI("WOW: numDiff is %d, max %d", numDiff, kMaxDiffBits);
                }
            } else {
                pStats->numDiffBits[numDiff]++;
            }
        }

        /* advance to start of next line */
        rawMap += pMap->regWidth;

        prevAddr = addr;
        prevData = dataStart;
    }
}
#endif

/*
 * Compute the difference between two bit vectors.
 *
 * If "lebOutBuf" is non-NULL, we output the bit indices in ULEB128 format
 * as we go.  Otherwise, we just generate the various counts.
 *
 * The bit vectors are compared byte-by-byte, so any unused bits at the
 * end must be zero.
 *
 * Returns the number of bytes required to hold the ULEB128 output.
 *
 * If "pFirstBitChanged" or "pNumBitsChanged" are non-NULL, they will
 * receive the index of the first changed bit and the number of changed
 * bits, respectively.
 */
static int computeBitDiff(const u1* bits1, const u1* bits2, int byteWidth,
    int* pFirstBitChanged, int* pNumBitsChanged, u1* lebOutBuf)
{
    int numBitsChanged = 0;
    int firstBitChanged = -1;
    int lebSize = 0;
    int byteNum;

    /*
     * Run through the vectors, first comparing them at the byte level.  This
     * will yield a fairly quick result if nothing has changed between them.
     */
    for (byteNum = 0; byteNum < byteWidth; byteNum++) {
        u1 byte1 = *bits1++;
        u1 byte2 = *bits2++;
        if (byte1 != byte2) {
            /*
             * Walk through the byte, identifying the changed bits.
             */
            int bitNum;
            for (bitNum = 0; bitNum < 8; bitNum++) {
                if (((byte1 >> bitNum) & 0x01) != ((byte2 >> bitNum) & 0x01)) {
                    int bitOffset = (byteNum << 3) + bitNum;

                    if (firstBitChanged < 0)
                        firstBitChanged = bitOffset;
                    numBitsChanged++;

                    if (lebOutBuf == NULL) {
                        lebSize += unsignedLeb128Size(bitOffset);
                    } else {
                        u1* curBuf = lebOutBuf;
                        lebOutBuf = writeUnsignedLeb128(lebOutBuf, bitOffset);
                        lebSize += lebOutBuf - curBuf;
                    }
                }
            }
        }
    }

    if (numBitsChanged > 0)
        assert(firstBitChanged >= 0);

    if (pFirstBitChanged != NULL)
        *pFirstBitChanged = firstBitChanged;
    if (pNumBitsChanged != NULL)
        *pNumBitsChanged = numBitsChanged;

    return lebSize;
}

/*
 * Compress the register map with differential encoding.
 *
 * "meth" is only needed for debug output.
 *
 * On success, returns a newly-allocated RegisterMap.  If the map is not
 * compatible for some reason, or fails to get smaller, this will return NULL.
 */
static RegisterMap* compressMapDifferential(const RegisterMap* pMap,
    const Method* meth)
{
    RegisterMap* pNewMap = NULL;
    int origSize = computeRegisterMapSize(pMap);
    u1* tmpPtr;
    int addrWidth, regWidth, numEntries;
    bool debug = false;

    if (false &&
        strcmp(meth->clazz->descriptor, "Landroid/text/StaticLayout;") == 0 &&
        strcmp(meth->name, "generate") == 0)
    {
        debug = true;
    }

    u1 format = dvmRegisterMapGetFormat(pMap);
    switch (format) {
    case kRegMapFormatCompact8:
        addrWidth = 1;
        break;
    case kRegMapFormatCompact16:
        addrWidth = 2;
        break;
    default:
        LOGE("ERROR: can't compress map with format=%d", format);
        return NULL;
    }

    regWidth = dvmRegisterMapGetRegWidth(pMap);
    numEntries = dvmRegisterMapGetNumEntries(pMap);

    if (debug) {
        LOGI("COMPRESS: %s.%s aw=%d rw=%d ne=%d",
            meth->clazz->descriptor, meth->name,
            addrWidth, regWidth, numEntries);
        dumpRegisterMap(pMap, -1);
    }

    if (numEntries <= 1) {
        LOGV("Can't compress map with 0 or 1 entries");
        return NULL;
    }

    /*
     * We don't know how large the compressed data will be.  It's possible
     * for it to expand and become larger than the original.  The header
     * itself is variable-sized, so we generate everything into a temporary
     * buffer and then copy it to form-fitting storage once we know how big
     * it will be (and that it's smaller than the original).
     *
     * If we use a size that is equal to the size of the input map plus
     * a value longer than a single entry can possibly expand to, we need
     * only check for overflow at the end of each entry.  The worst case
     * for a single line is (1 + <ULEB8 address> + <full copy of vector>).
     * Addresses are 16 bits, so that's (1 + 3 + regWidth).
     *
     * The initial address offset and bit vector will take up less than
     * or equal to the amount of space required when uncompressed -- large
     * initial offsets are rejected.
     */
    UniquePtr<u1[]> tmpBuf(new u1[origSize + (1 + 3 + regWidth)]);
    if (tmpBuf.get() == NULL)
        return NULL;

    tmpPtr = tmpBuf.get();

    const u1* mapData = pMap->data;
    const u1* prevBits;
    u2 addr, prevAddr;

    addr = *mapData++;
    if (addrWidth > 1)
        addr |= (*mapData++) << 8;

    if (addr >= 128) {
        LOGV("Can't compress map with starting address >= 128");
        return NULL;
    }

    /*
     * Start by writing the initial address and bit vector data.  The high
     * bit of the initial address is used to indicate the required address
     * width (which the decoder can't otherwise determine without parsing
     * the compressed data).
     */
    *tmpPtr++ = addr | (addrWidth > 1 ? 0x80 : 0x00);
    memcpy(tmpPtr, mapData, regWidth);

    prevBits = mapData;
    prevAddr = addr;

    tmpPtr += regWidth;
    mapData += regWidth;

    /*
     * Loop over all following entries.
     */
    for (int entry = 1; entry < numEntries; entry++) {
        int addrDiff;
        u1 key;

        /*
         * Pull out the address and figure out how to encode it.
         */
        addr = *mapData++;
        if (addrWidth > 1)
            addr |= (*mapData++) << 8;

        if (debug)
            LOGI(" addr=0x%04x ent=%d (aw=%d)", addr, entry, addrWidth);

        addrDiff = addr - prevAddr;
        assert(addrDiff > 0);
        if (addrDiff < 8) {
            /* small difference, encode in 3 bits */
            key = addrDiff -1;          /* set 00000AAA */
            if (debug)
                LOGI(" : small %d, key=0x%02x", addrDiff, key);
        } else {
            /* large difference, output escape code */
            key = 0x07;                 /* escape code for AAA */
            if (debug)
                LOGI(" : large %d, key=0x%02x", addrDiff, key);
        }

        int numBitsChanged, firstBitChanged, lebSize;

        lebSize = computeBitDiff(prevBits, mapData, regWidth,
            &firstBitChanged, &numBitsChanged, NULL);

        if (debug) {
            LOGI(" : diff fbc=%d nbc=%d ls=%d (rw=%d)",
                firstBitChanged, numBitsChanged, lebSize, regWidth);
        }

        if (numBitsChanged == 0) {
            /* set B to 1 and CCCC to zero to indicate no bits were changed */
            key |= 0x08;
            if (debug) LOGI(" : no bits changed");
        } else if (numBitsChanged == 1 && firstBitChanged < 16) {
            /* set B to 0 and CCCC to the index of the changed bit */
            key |= firstBitChanged << 4;
            if (debug) LOGI(" : 1 low bit changed");
        } else if (numBitsChanged < 15 && lebSize < regWidth) {
            /* set B to 1 and CCCC to the number of bits */
            key |= 0x08 | (numBitsChanged << 4);
            if (debug) LOGI(" : some bits changed");
        } else {
            /* set B to 1 and CCCC to 0x0f so we store the entire vector */
            key |= 0x08 | 0xf0;
            if (debug) LOGI(" : encode original");
        }

        /*
         * Encode output.  Start with the key, follow with the address
         * diff (if it didn't fit in 3 bits), then the changed bit info.
         */
        *tmpPtr++ = key;
        if ((key & 0x07) == 0x07)
            tmpPtr = writeUnsignedLeb128(tmpPtr, addrDiff);

        if ((key & 0x08) != 0) {
            int bitCount = key >> 4;
            if (bitCount == 0) {
                /* nothing changed, no additional output required */
            } else if (bitCount == 15) {
                /* full vector is most compact representation */
                memcpy(tmpPtr, mapData, regWidth);
                tmpPtr += regWidth;
            } else {
                /* write bit indices in LEB128 format */
                (void) computeBitDiff(prevBits, mapData, regWidth,
                    NULL, NULL, tmpPtr);
                tmpPtr += lebSize;
            }
        } else {
            /* single-bit changed, value encoded in key byte */
        }

        prevBits = mapData;
        prevAddr = addr;
        mapData += regWidth;

        /*
         * See if we've run past the original size.
         */
        if (tmpPtr - tmpBuf.get() >= origSize) {
            if (debug) {
                LOGD("Compressed size >= original (%d vs %d): %s.%s",
                    tmpPtr - tmpBuf.get(), origSize,
                    meth->clazz->descriptor, meth->name);
            }
            return NULL;
        }
    }

    /*
     * Create a RegisterMap with the contents.
     *
     * TODO: consider using a threshold other than merely ">=".  We would
     * get poorer compression but potentially use less native heap space.
     */
    static const int kHeaderSize = offsetof(RegisterMap, data);
    int newDataSize = tmpPtr - tmpBuf.get();
    int newMapSize;

    newMapSize = kHeaderSize + unsignedLeb128Size(newDataSize) + newDataSize;
    if (newMapSize >= origSize) {
        if (debug) {
            LOGD("Final comp size >= original (%d vs %d): %s.%s",
                newMapSize, origSize, meth->clazz->descriptor, meth->name);
        }
        return NULL;
    }

    pNewMap = (RegisterMap*) malloc(newMapSize);
    if (pNewMap == NULL)
        return NULL;
    dvmRegisterMapSetFormat(pNewMap, kRegMapFormatDifferential);
    dvmRegisterMapSetOnHeap(pNewMap, true);
    dvmRegisterMapSetRegWidth(pNewMap, regWidth);
    dvmRegisterMapSetNumEntries(pNewMap, numEntries);

    tmpPtr = pNewMap->data;
    tmpPtr = writeUnsignedLeb128(tmpPtr, newDataSize);
    memcpy(tmpPtr, tmpBuf.get(), newDataSize);

    if (REGISTER_MAP_VERBOSE) {
        LOGD("Compression successful (%d -> %d) from aw=%d rw=%d ne=%d",
            computeRegisterMapSize(pMap), computeRegisterMapSize(pNewMap),
            addrWidth, regWidth, numEntries);
    }

    return pNewMap;
}

/*
 * Toggle the value of the "idx"th bit in "ptr".
 */
static inline void toggleBit(u1* ptr, int idx)
{
    ptr[idx >> 3] ^= 1 << (idx & 0x07);
}

/*
 * Expand a compressed map to an uncompressed form.
 *
 * Returns a newly-allocated RegisterMap on success, or NULL on failure.
 *
 * TODO: consider using the linear allocator or a custom allocator with
 * LRU replacement for these instead of the native heap.
 */
static RegisterMap* uncompressMapDifferential(const RegisterMap* pMap)
{
    static const int kHeaderSize = offsetof(RegisterMap, data);
    u1 format = dvmRegisterMapGetFormat(pMap);
    RegisterMapFormat newFormat;
    int regWidth, numEntries, newAddrWidth, newMapSize;

    if (format != kRegMapFormatDifferential) {
        LOGE("Not differential (%d)", format);
        return NULL;
    }

    regWidth = dvmRegisterMapGetRegWidth(pMap);
    numEntries = dvmRegisterMapGetNumEntries(pMap);

    /* get the data size; we can check this at the end */
    const u1* srcPtr = pMap->data;
    int expectedSrcLen = readUnsignedLeb128(&srcPtr);
    const u1* srcStart = srcPtr;

    /* get the initial address and the 16-bit address flag */
    int addr = *srcPtr & 0x7f;
    if ((*srcPtr & 0x80) == 0) {
        newFormat = kRegMapFormatCompact8;
        newAddrWidth = 1;
    } else {
        newFormat = kRegMapFormatCompact16;
        newAddrWidth = 2;
    }
    srcPtr++;

    /* now we know enough to allocate the new map */
    if (REGISTER_MAP_VERBOSE) {
        LOGI("Expanding to map aw=%d rw=%d ne=%d",
            newAddrWidth, regWidth, numEntries);
    }
    newMapSize = kHeaderSize + (newAddrWidth + regWidth) * numEntries;
    RegisterMap* pNewMap = (RegisterMap*) malloc(newMapSize);

    if (pNewMap == NULL)
      return NULL;

    dvmRegisterMapSetFormat(pNewMap, newFormat);
    dvmRegisterMapSetOnHeap(pNewMap, true);
    dvmRegisterMapSetRegWidth(pNewMap, regWidth);
    dvmRegisterMapSetNumEntries(pNewMap, numEntries);

    /*
     * Write the start address and initial bits to the new map.
     */
    u1* dstPtr = pNewMap->data;

    *dstPtr++ = addr & 0xff;
    if (newAddrWidth > 1)
        *dstPtr++ = (u1) (addr >> 8);

    memcpy(dstPtr, srcPtr, regWidth);

    int prevAddr = addr;
    const u1* prevBits = dstPtr;    /* point at uncompressed data */

    dstPtr += regWidth;
    srcPtr += regWidth;

    /*
     * Walk through, uncompressing one line at a time.
     */
    int entry;
    for (entry = 1; entry < numEntries; entry++) {
        int addrDiff;
        u1 key;

        key = *srcPtr++;

        /* get the address */
        if ((key & 0x07) == 7) {
            /* address diff follows in ULEB128 */
            addrDiff = readUnsignedLeb128(&srcPtr);
        } else {
            addrDiff = (key & 0x07) +1;
        }

        addr = prevAddr + addrDiff;
        *dstPtr++ = addr & 0xff;
        if (newAddrWidth > 1)
            *dstPtr++ = (u1) (addr >> 8);

        /* unpack the bits */
        if ((key & 0x08) != 0) {
            int bitCount = (key >> 4);
            if (bitCount == 0) {
                /* no bits changed, just copy previous */
                memcpy(dstPtr, prevBits, regWidth);
            } else if (bitCount == 15) {
                /* full copy of bit vector is present; ignore prevBits */
                memcpy(dstPtr, srcPtr, regWidth);
                srcPtr += regWidth;
            } else {
                /* copy previous bits and modify listed indices */
                memcpy(dstPtr, prevBits, regWidth);
                while (bitCount--) {
                    int bitIndex = readUnsignedLeb128(&srcPtr);
                    toggleBit(dstPtr, bitIndex);
                }
            }
        } else {
            /* copy previous bits and modify the specified one */
            memcpy(dstPtr, prevBits, regWidth);

            /* one bit, from 0-15 inclusive, was changed */
            toggleBit(dstPtr, key >> 4);
        }

        prevAddr = addr;
        prevBits = dstPtr;
        dstPtr += regWidth;
    }

    if (dstPtr - (u1*) pNewMap != newMapSize) {
        LOGE("ERROR: output %d bytes, expected %d",
            dstPtr - (u1*) pNewMap, newMapSize);
        free(pNewMap);
        return NULL;
    }

    if (srcPtr - srcStart != expectedSrcLen) {
        LOGE("ERROR: consumed %d bytes, expected %d",
            srcPtr - srcStart, expectedSrcLen);
        free(pNewMap);
        return NULL;
    }

    if (REGISTER_MAP_VERBOSE) {
        LOGD("Expansion successful (%d -> %d)",
            computeRegisterMapSize(pMap), computeRegisterMapSize(pNewMap));
    }

    return pNewMap;
}
