Exemplo n.º 1
0
/* Basically we need to cleanup any state kept around for this thread and let
 * the other side know the thread is exiting if needed. */
void offThreadExited(Thread* self) {
  u4 threadId = self->threadId;

  /* Inform the other endpoint that we're exiting if started locally.  We can
   * avoid this if the other endpoint doesn't even know about this thread. */
  if((threadId & 0x8000) == (gDvm.isServer ? 0x8000 : 0)) {
    if(!self->offLocalOnly) {
      offWriteU1(self, OFF_ACTION_DEATH);
      offSyncPush();

      ALOGI("THREAD %d WAITING FOR SIGNOFF", threadId);
      offThreadWaitForResume(self);
      ALOGI("THREAD %d SIGNING OFF", threadId);
    }
  }

  /* Remove the thread from the thread table. */
  if(gDvm.offThreadTable) {
    dvmHashTableLock(gDvm.offThreadTable);
    dvmHashTableRemove(gDvm.offThreadTable, threadId, self);
    dvmHashTableUnlock(gDvm.offThreadTable);
  }

  offFlushStream(self);
  if((threadId & 0x8000) == (gDvm.isServer ? 0x8000 : 0)) {
    dvmClearBit(gDvm.threadIdMap, ((threadId & 0x7FFF) >> 1) - 1);
  } else {
Exemplo n.º 2
0
int
hprofShutdown_Stack()
{
    HashIter iter;

    /* This will be called when a GC has completed. */
    for (dvmHashIterBegin(gStackTraceHashTable, &iter);
         !dvmHashIterDone(&iter);
         dvmHashIterNext(&iter)) {
        StackTraceEntry *stackTraceEntry;

        /*
         * If the 'live' bit is 0, the trace is not in use by any current
         * heap object and may be destroyed.
         */
        stackTraceEntry = (StackTraceEntry *) dvmHashIterData(&iter);
        if (!stackTraceEntry->live) {
            dvmHashTableRemove(gStackTraceHashTable,
                    computeStackTraceHash(stackTraceEntry), stackTraceEntry);
            free(stackTraceEntry);
        }
    }

    return 0;
}
Exemplo n.º 3
0
static StringObject* lookupInternedString(StringObject* strObj, bool isLiteral)
{
    StringObject* found;

    assert(strObj != NULL);
    u4 key = dvmComputeStringHash(strObj);
    dvmLockMutex(&gDvm.internLock);
    if (isLiteral) {
        /*
         * Check the literal table for a match.
         */
        StringObject* literal = lookupString(gDvm.literalStrings, key, strObj);
        if (literal != NULL) {
            /*
             * A match was found in the literal table, the easy case.
             */
            found = literal;
        } else {
            /*
             * There is no match in the literal table, check the
             * interned string table.
             */
            StringObject* interned = lookupString(gDvm.internedStrings, key, strObj);
            if (interned != NULL) {
                /*
                 * A match was found in the interned table.  Move the
                 * matching string to the literal table.
                 */
                dvmHashTableRemove(gDvm.internedStrings, key, interned);
                found = insertString(gDvm.literalStrings, key, interned);
                assert(found == interned);
            } else {
                /*
                 * No match in the literal table or the interned
                 * table.  Insert into the literal table.
                 */
                found = insertString(gDvm.literalStrings, key, strObj);
                assert(found == strObj);
            }
        }
    } else {
        /*
         * Check the literal table for a match.
         */
        found = lookupString(gDvm.literalStrings, key, strObj);
        if (found == NULL) {
            /*
             * No match was found in the literal table.  Insert into
             * the intern table if it does not already exist.
             */
            found = insertString(gDvm.internedStrings, key, strObj);
        }
    }
    assert(found != NULL);
    dvmUnlockMutex(&gDvm.internLock);
    return found;
}
/*
 * private static void closeDexFile(int cookie)
 *
 * Release resources associated with a user-loaded DEX file.
 */
static void Dalvik_dalvik_system_DexFile_closeDexFile(const u4* args,
    JValue* pResult)
{
    int cookie = args[0];
    DexOrJar* pDexOrJar = (DexOrJar*) cookie;

    if (pDexOrJar == NULL)
        RETURN_VOID();

    LOGV("Closing DEX file %p (%s)\n", pDexOrJar, pDexOrJar->fileName);

    if (!validateCookie(cookie))
        RETURN_VOID();

    /*
     * We can't just free arbitrary DEX files because they have bits and
     * pieces of loaded classes.  The only exception to this rule is if
     * they were never used to load classes.
     *
     * If we can't free them here, dvmInternalNativeShutdown() will free
     * them when the VM shuts down.
     */
    if (pDexOrJar->okayToFree) {
        u4 hash = dvmComputeUtf8Hash(pDexOrJar->fileName);
        dvmHashTableLock(gDvm.userDexFiles);
        if (!dvmHashTableRemove(gDvm.userDexFiles, hash, pDexOrJar)) {
            LOGW("WARNING: could not remove '%s' from DEX hash table\n",
                pDexOrJar->fileName);
        }
        dvmHashTableUnlock(gDvm.userDexFiles);
        LOGV("+++ freeing DexFile '%s' resources\n", pDexOrJar->fileName);
        dvmFreeDexOrJar(pDexOrJar);
    } else {
        LOGV("+++ NOT freeing DexFile '%s' resources\n", pDexOrJar->fileName);
    }

    RETURN_VOID();
}
Exemplo n.º 5
0
/*
 * Some quick hash table tests.
 */
bool dvmTestHash()
{
    HashTable* pTab;
    char tmpStr[64];
    const char* str;
    u4 hash;
    int i;

    ALOGV("TestHash BEGIN");

    pTab = dvmHashTableCreate(dvmHashSize(12), free);
    if (pTab == NULL)
        return false;

    dvmHashTableLock(pTab);

    /* add some entries */
    for (i = 0; i < kNumTestEntries; i++) {
        sprintf(tmpStr, "entry %d", i);
        hash = dvmComputeUtf8Hash(tmpStr);
        dvmHashTableLookup(pTab, hash, strdup(tmpStr),
            (HashCompareFunc) strcmp, true);
    }

    dvmHashTableUnlock(pTab);

    /* make sure we can find all entries */
    for (i = 0; i < kNumTestEntries; i++) {
        sprintf(tmpStr, "entry %d", i);
        hash = dvmComputeUtf8Hash(tmpStr);
        str = (const char*) dvmHashTableLookup(pTab, hash, tmpStr,
                (HashCompareFunc) strcmp, false);
        if (str == NULL) {
            ALOGE("TestHash: failure: could not find '%s'", tmpStr);
            /* return false */
        }
    }

    /* make sure it behaves correctly when entry not found and !doAdd */
    sprintf(tmpStr, "entry %d", 17);
    hash = dvmComputeUtf8Hash(tmpStr);
    str = (const char*) dvmHashTableLookup(pTab, hash, tmpStr,
            (HashCompareFunc) strcmp, false);
    if (str == NULL) {
        /* good */
    } else {
        ALOGE("TestHash found nonexistent string (improper add?)");
    }

    dumpForeach(pTab);
    dumpIterator(pTab);

    /* make sure they all get freed */
    dvmHashTableFree(pTab);


    /*
     * Round 2: verify probing & tombstones.
     */
    pTab = dvmHashTableCreate(dvmHashSize(2), free);
    if (pTab == NULL)
        return false;

    hash = 0;

    /* two entries, same hash, different values */
    const char* str1;
    str1 = (char*) dvmHashTableLookup(pTab, hash, strdup("one"),
            (HashCompareFunc) strcmp, true);
    assert(str1 != NULL);
    str = (const char*) dvmHashTableLookup(pTab, hash, strdup("two"),
            (HashCompareFunc) strcmp, true);

    /* remove the first one */
    if (!dvmHashTableRemove(pTab, hash, (void*)str1))
        ALOGE("TestHash failed to delete item");
    else
        free((void*)str1);     // "Remove" doesn't call the free func

    /* make sure iterator doesn't included deleted entries */
    int count = 0;
    HashIter iter;
    for (dvmHashIterBegin(pTab, &iter); !dvmHashIterDone(&iter);
        dvmHashIterNext(&iter))
    {
        count++;
    }
    if (count != 1) {
        ALOGE("TestHash wrong number of entries (%d)", count);
    }

    /* see if we can find them */
    str = (const char*) dvmHashTableLookup(pTab, hash, (void*)"one",
            (HashCompareFunc) strcmp,false);
    if (str != NULL)
        ALOGE("TestHash deleted entry has returned!");
    str = (const char*) dvmHashTableLookup(pTab, hash, (void*)"two",
            (HashCompareFunc) strcmp,false);
    if (str == NULL)
        ALOGE("TestHash entry vanished");

    /* force a table realloc to exercise tombstone removal */
    for (i = 0; i < 20; i++) {
        sprintf(tmpStr, "entry %d", i);
        str = (const char*) dvmHashTableLookup(pTab, hash, strdup(tmpStr),
                (HashCompareFunc) strcmp, true);
        assert(str != NULL);
    }

    dvmHashTableFree(pTab);
    ALOGV("TestHash END");

    return true;
}