Esempio n. 1
0
/**
 * Returns the ReferentEntry for the specified object or creates one and adds
 * it to the referents hash if none exists. referentsLock MUST be held.
 */
static ReferentEntry* getReferentEntryForObject(Env* env, Object* o) {
    void* key = (void*) GC_HIDE_POINTER(o); // Hide the pointer from the GC so that the key doesn't prevent the object from being GCed.
    ReferentEntry* referentEntry;
    HASH_FIND_PTR(referents, &key, referentEntry);
    if (!referentEntry) {
        // Object is not in the hashtable. Add it.
        referentEntry = allocateMemoryOfKind(env, sizeof(ReferentEntry), referentEntryGCKind);
        if (!referentEntry) return NULL; // OOM thrown
        referentEntry->key = key;
        HASH_ADD_PTR(referents, key, referentEntry);
    }
    return referentEntry;
}
Esempio n. 2
0
/**
 * Adds a string to the cache of interned string. The string must not already be
 * interned.  The internedStringsLock MUST be held when calling this function.
 */
static jboolean addInternedString(Env* env, const char* s,  Object* string) {
    CacheEntry* cacheEntry = allocateMemoryOfKind(env, sizeof(CacheEntry), cacheEntryGCKind);
    if (!cacheEntry) {
        return FALSE;
    }

    cacheEntry->key = s;
    cacheEntry->string = string;
    HASH_ADD_KEYPTR(hh, internedStrings, cacheEntry->key, strlen(cacheEntry->key), cacheEntry);

    // prune the cache to MAX_CACHE_SIZE
    if (HASH_COUNT(internedStrings) >= MAX_CACHE_SIZE) {
        CacheEntry* tmpEntry;
        HASH_ITER(hh, internedStrings, cacheEntry, tmpEntry) {
            // prune the first entry (loop is based on insertion order so this deletes the oldest item)
            HASH_DELETE(hh, internedStrings, cacheEntry);
            break;
        }