Ejemplo n.º 1
0
void
js_InitAtomMap(JSContext *cx, JSAtomMap *map, JSAtomList *al)
{
    JSAtom **vector;
    JSAtomListElement *ale;
    uint32 count;

    /* Map length must already be initialized. */
    JS_ASSERT(al->count == map->length);
#ifdef DEBUG
    JS_ATOMIC_INCREMENT(&js_atom_map_count);
#endif
    ale = (JSAtomListElement *)al->list;
    if (!ale && !al->table) {
        JS_ASSERT(!map->vector);
        return;
    }

    count = al->count;
    vector = map->vector;
    if (al->table) {
#ifdef DEBUG
        JS_ATOMIC_INCREMENT(&js_atom_map_hash_table_count);
#endif
        JS_HashTableEnumerateEntries(al->table, js_map_atom, vector);
    } else {
        do {
            vector[ALE_INDEX(ale)] = ALE_ATOM(ale);
        } while ((ale = ALE_NEXT(ale)) != NULL);
    }
    al->clear();
}
Ejemplo n.º 2
0
JSAtomListElement *
js_IndexAtom(JSContext *cx, JSAtom *atom, JSAtomList *al)
{
    JSAtomListElement *ale, *ale2, *next;
    JSHashEntry **hep;

    ATOM_LIST_LOOKUP(ale, hep, al, atom);
    if (!ale) {
        if (al->count < 10) {
            /* Few enough for linear search, no hash table needed. */
            JS_ASSERT(!al->table);
            ale = (JSAtomListElement *)js_alloc_temp_entry(cx, atom);
            if (!ale)
                return NULL;
            ALE_SET_ATOM(ale, atom);
            ALE_SET_NEXT(ale, al->list);
            al->list = ale;
        } else {
            /* We want to hash.  Have we already made a hash table? */
            if (!al->table) {
                /* No hash table yet, so hep had better be null! */
                JS_ASSERT(!hep);
                al->table = JS_NewHashTable(al->count + 1, js_hash_atom_ptr,
                                            JS_CompareValues, JS_CompareValues,
                                            &temp_alloc_ops, cx);
                if (!al->table)
                    return NULL;

                /*
                 * Set ht->nentries explicitly, because we are moving entries
                 * from al to ht, not calling JS_HashTable(Raw|)Add.
                 */
                al->table->nentries = al->count;

                /* Insert each ale on al->list into the new hash table. */
                for (ale2 = al->list; ale2; ale2 = next) {
                    next = ALE_NEXT(ale2);
                    ale2->entry.keyHash = ALE_ATOM(ale2)->number;
                    hep = JS_HashTableRawLookup(al->table, ale2->entry.keyHash,
                                                ale2->entry.key);
                    ALE_SET_NEXT(ale2, *hep);
                    *hep = &ale2->entry;
                }
                al->list = NULL;

                /* Set hep for insertion of atom's ale, immediately below. */
                hep = JS_HashTableRawLookup(al->table, atom->number, atom);
            }

            /* Finally, add an entry for atom into the hash bucket at hep. */
            ale = (JSAtomListElement *)
                  JS_HashTableRawAdd(al->table, hep, atom->number, atom, NULL);
            if (!ale)
                return NULL;
        }

        ALE_SET_INDEX(ale, al->count++);
    }
    return ale;
}
Ejemplo n.º 3
0
js_map_atom(JSHashEntry *he, intN i, void *arg)
{
    JSAtomListElement *ale = (JSAtomListElement *)he;
    JSAtom **vector = arg;

    vector[ALE_INDEX(ale)] = ALE_ATOM(ale);
    return HT_ENUMERATE_NEXT;
}
Ejemplo n.º 4
0
js_InitAtomMap(JSContext *cx, JSAtomMap *map, JSAtomList *al)
{
    JSAtom **vector;
    JSAtomListElement *ale;
    uint32 count;

#ifdef DEBUG
    JS_ATOMIC_INCREMENT(&js_atom_map_count);
#endif
    ale = al->list;
    if (!ale && !al->table) {
        map->vector = NULL;
        map->length = 0;
        return JS_TRUE;
    }

    count = al->count;
    if (count >= ATOM_INDEX_LIMIT) {
        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
                             JSMSG_TOO_MANY_LITERALS);
        return JS_FALSE;
    }
    vector = (JSAtom **) JS_malloc(cx, (size_t) count * sizeof *vector);
    if (!vector)
        return JS_FALSE;

    if (al->table) {
#ifdef DEBUG
        JS_ATOMIC_INCREMENT(&js_atom_map_hash_table_count);
#endif
        JS_HashTableEnumerateEntries(al->table, js_map_atom, vector);
    } else {
        do {
            vector[ALE_INDEX(ale)] = ALE_ATOM(ale);
        } while ((ale = ALE_NEXT(ale)) != NULL);
    }
    ATOM_LIST_INIT(al);

    map->vector = vector;
    map->length = (jsatomid)count;
    return JS_TRUE;
}
Ejemplo n.º 5
0
JSAtomListElement *
JSAtomList::rawLookup(JSAtom *atom, JSHashEntry **&hep)
{
    JSAtomListElement *ale;

    if (table) {
        hep = JS_HashTableRawLookup(table, ATOM_HASH(atom), atom);
        ale = *hep ? (JSAtomListElement *) *hep : NULL;
    } else {
        JSHashEntry **alep = &list;
        hep = NULL;
        while ((ale = (JSAtomListElement *)*alep) != NULL) {
            if (ALE_ATOM(ale) == atom) {
                /* Hit, move atom's element to the front of the list. */
                *alep = ale->entry.next;
                ale->entry.next = list;
                list = &ale->entry;
                break;
            }
            alep = &ale->entry.next;
        }
    }
    return ale;
}
Ejemplo n.º 6
0
JSAtomListElement *
JSAtomList::add(JSCompiler *jsc, JSAtom *atom, AddHow how)
{
    JS_ASSERT(!set);

    JSAtomListElement *ale, *ale2, *next;
    JSHashEntry **hep;

    ale = rawLookup(atom, hep);
    if (!ale || how != UNIQUE) {
        if (count < ATOM_LIST_HASH_THRESHOLD && !table) {
            /* Few enough for linear search and no hash table yet needed. */
            ale = (JSAtomListElement *)js_alloc_temp_entry(jsc, atom);
            if (!ale)
                return NULL;
            ALE_SET_ATOM(ale, atom);

            if (how == HOIST) {
                ale->entry.next = NULL;
                hep = (JSHashEntry **) &list;
                while (*hep)
                    hep = &(*hep)->next;
                *hep = &ale->entry;
            } else {
                ale->entry.next = list;
                list = &ale->entry;
            }
        } else {
            /*
             * We should hash, or else we already are hashing, but count was
             * reduced by JSAtomList::rawRemove below ATOM_LIST_HASH_THRESHOLD.
             * Check whether we should create the table.
             */
            if (!table) {
                /* No hash table yet, so hep had better be null! */
                JS_ASSERT(!hep);
                table = JS_NewHashTable(count + 1, js_hash_atom_ptr,
                                        JS_CompareValues, JS_CompareValues,
                                        &temp_alloc_ops, jsc);
                if (!table)
                    return NULL;

                /*
                 * Set ht->nentries explicitly, because we are moving entries
                 * from list to ht, not calling JS_HashTable(Raw|)Add.
                 */
                table->nentries = count;

                /*
                 * Insert each ale on list into the new hash table. Append to
                 * the hash chain rather than inserting at the bucket head, to
                 * preserve order among entries with the same key.
                 */
                for (ale2 = (JSAtomListElement *)list; ale2; ale2 = next) {
                    next = ALE_NEXT(ale2);
                    ale2->entry.keyHash = ATOM_HASH(ALE_ATOM(ale2));
                    hep = JS_HashTableRawLookup(table, ale2->entry.keyHash,
                                                ale2->entry.key);
                    while (*hep)
                        hep = &(*hep)->next;
                    *hep = &ale2->entry;
                    ale2->entry.next = NULL;
                }
                list = NULL;

                /* Set hep for insertion of atom's ale, immediately below. */
                hep = JS_HashTableRawLookup(table, ATOM_HASH(atom), atom);
            }

            /* Finally, add an entry for atom into the hash bucket at hep. */
            ale = (JSAtomListElement *)
                  JS_HashTableRawAdd(table, hep, ATOM_HASH(atom), atom, NULL);
            if (!ale)
                return NULL;

            /*
             * If hoisting, move ale to the end of its chain after we called
             * JS_HashTableRawAdd, since RawAdd may have grown the table and
             * then recomputed hep to refer to the pointer to the first entry
             * with the given key.
             */
            if (how == HOIST && ale->entry.next) {
                JS_ASSERT(*hep == &ale->entry);
                *hep = ale->entry.next;
                ale->entry.next = NULL;
                do {
                    hep = &(*hep)->next;
                } while (*hep);
                *hep = &ale->entry;
            }
        }

        ALE_SET_INDEX(ale, count++);
    }
    return ale;
}