示例#1
0
void freeInternedStrings() {
    int unmarked = 0;

    hashIterateP(hash_table);

    if(unmarked) {
        int size;

        /* Update count to remaining number of strings */
        hash_table.hash_count -= unmarked;

        /* Calculate nearest multiple of 2 larger than count */
        for(size = 1; size < hash_table.hash_count; size <<= 1);

        /* Ensure new table is less than 2/3 full */
        size = hash_table.hash_count*3 > size*2 ? size<< 1 : size;

        resizeHash(&hash_table, size);
    }
}
示例#2
0
//The following function is converted from the macro with the same name,since it may lead compiling error under
//Microsoft Visual Studio.
static void _findHashEntry(HashTable* table,Object* ptr,Monitor* ptr2,int add_if_absent,int scavenge,int locked)
{                                                                                  
    int hash;                                                                      
    int i;                                                                         
	Thread *self;                                                                  
                                                                                   
	hash = HASH(ptr);                                                              
    if(locked) {                                                                   
        self = threadSelf();                                                       
        lockHashTable0(table, self);                                              
    }                                                                              
                                                                                   
    i = hash & (table->hash_size - 1);                                             
                                                                                   
    for(;;) {                                                                      
        ptr2 = table->hash_table[i].data;                                          
        if((ptr2 == NULL) || (COMPARE(ptr, ptr2, hash, table->hash_table[i].hash))) 
            break;                                                                 
                                                                                   
        i = (i+1) & (table->hash_size - 1);                                        
    }                                                                              
                                                                                   
    if(ptr2) {                                                                     
        ptr2 = FOUND(ptr, ptr2);                                                   
    } else                                                                         
        if(add_if_absent) {                                                        
            table->hash_table[i].hash = hash;                                      
            ptr2 = table->hash_table[i].data = PREPARE(ptr);                       
                                                                                   
            if(ptr2) {                                                             
                table->hash_count++;                                               
                if((table->hash_count * 4) > (table->hash_size * 3)) {             
                    int new_size;                                                  
                    if(scavenge) {                                                 
                        HashEntry *entry = table->hash_table;                      
                        int cnt = table->hash_count;                               
                        for(; cnt; entry++) {                                      
                            void *data = entry->data;                              
                            if(data) {                                             
                                if(SCAVENGE(data)) {                               
                                    entry->data = NULL;                            
                                    table->hash_count--;                           
                                }                                                  
                                cnt--;                                             
                            }                                                      
                        }                                                          
                        if((table->hash_count * 3) > (table->hash_size * 2))       
                            new_size = table->hash_size*2;                         
                        else                                                       
                            new_size = table->hash_size;                           
                    } else                                                         
                        new_size = table->hash_size*2;                             
                                                                                   
                    resizeHash(table, new_size);                                  
                }                                                                 
            }                                                                     
        }                                                                         
                                                                                  
    if(locked)                                                                    
        unlockHashTable0(table, self);                                            
}
示例#3
0
/*
 * Look up an entry.
 *
 * We probe on collisions, wrapping around the table.
 */
void* dvmHashTableLookup(HashTable* pHashTable, u4 itemHash, void* item,
    HashCompareFunc cmpFunc, bool doAdd)
{
    HashEntry* pEntry;
    HashEntry* pEnd;
    void* result = NULL;

    assert(pHashTable->tableSize > 0);
    assert(item != HASH_TOMBSTONE);
    assert(item != NULL);

    /* jump to the first entry and probe for a match */
    pEntry = &pHashTable->pEntries[itemHash & (pHashTable->tableSize-1)];
    pEnd = &pHashTable->pEntries[pHashTable->tableSize];
    while (pEntry->data != NULL) {
        if (pEntry->data != HASH_TOMBSTONE &&
            pEntry->hashValue == itemHash &&
            (*cmpFunc)(pEntry->data, item) == 0)
        {
            /* match */
            //LOGD("+++ match on entry %d\n", pEntry - pHashTable->pEntries);
            break;
        }

        pEntry++;
        if (pEntry == pEnd) {     /* wrap around to start */
            if (pHashTable->tableSize == 1)
                break;      /* edge case - single-entry table */
            pEntry = pHashTable->pEntries;
        }

        //LOGI("+++ look probing %d...\n", pEntry - pHashTable->pEntries);
    }

    if (pEntry->data == NULL) {
        if (doAdd) {
            pEntry->hashValue = itemHash;
            pEntry->data = item;
            pHashTable->numEntries++;

            /*
             * We've added an entry.  See if this brings us too close to full.
             */
            if ((pHashTable->numEntries+pHashTable->numDeadEntries) * LOAD_DENOM
                > pHashTable->tableSize * LOAD_NUMER)
            {
                if (!resizeHash(pHashTable, pHashTable->tableSize * 2)) {
                    /* don't really have a way to indicate failure */
                    LOGE("Dalvik hash resize failure\n");
                    dvmAbort();
                }
                /* note "pEntry" is now invalid */
            } else {
                //LOGW("okay %d/%d/%d\n",
                //    pHashTable->numEntries, pHashTable->tableSize,
                //    (pHashTable->tableSize * LOAD_NUMER) / LOAD_DENOM);
            }

            /* full table is bad -- search for nonexistent never halts */
            assert(pHashTable->numEntries < pHashTable->tableSize);
            result = item;
        } else {
            assert(result == NULL);
        }
    } else {
        result = pEntry->data;
    }

    return result;
}