Exemple #1
0
PL_HashTableRawAdd(PLHashTable *ht, PLHashEntry **hep,
                   PLHashNumber keyHash, const void *key, void *value)
{
    PRUint32 i, n;
    PLHashEntry *he, *next, **oldbuckets;
    PRSize nb;

    /* Grow the table if it is overloaded */
    n = NBUCKETS(ht);
    if (ht->nentries >= OVERLOADED(n)) {
        oldbuckets = ht->buckets;
#if defined(WIN16)
        if (2 * n > 16000)
            return 0;
#endif  /* WIN16 */
        nb = 2 * n * sizeof(PLHashEntry *);
        ht->buckets = (PLHashEntry**)
            ((*ht->allocOps->allocTable)(ht->allocPriv, nb));
        if (!ht->buckets) {
            ht->buckets = oldbuckets;
            return 0;
        }
        memset(ht->buckets, 0, nb);
#ifdef HASHMETER
        ht->ngrows++;
#endif
        ht->shift--;

        for (i = 0; i < n; i++) {
            for (he = oldbuckets[i]; he; he = next) {
                next = he->next;
                hep = PL_HashTableRawLookup(ht, he->keyHash, he->key);
                PR_ASSERT(*hep == 0);
                he->next = 0;
                *hep = he;
            }
        }
#ifdef DEBUG
        memset(oldbuckets, 0xDB, n * sizeof oldbuckets[0]);
#endif
        (*ht->allocOps->freeTable)(ht->allocPriv, oldbuckets);
        hep = PL_HashTableRawLookup(ht, keyHash, key);
    }

    /* Make a new key value entry */
    he = (*ht->allocOps->allocEntry)(ht->allocPriv, key);
    if (!he)
	return 0;
    he->keyHash = keyHash;
    he->key = key;
    he->value = value;
    he->next = *hep;
    *hep = he;
    ht->nentries++;
    return he;
}
Exemple #2
0
tmgraphnode *tmreader_component(tmreader *tmr, const char *name)
{
    PLHashNumber hash;

    hash = PL_HashString(name);
    return (tmgraphnode*) *PL_HashTableRawLookup(tmr->components, hash, name);
}
Exemple #3
0
tmgraphnode *tmreader_filename(tmreader *tmr, uint32 serial)
{
    const void *key;
    PLHashNumber hash;

    key = (const void*) serial;
    hash = hash_serial(key);
    return (tmgraphnode*) *PL_HashTableRawLookup(tmr->filenames, hash, key);
}
Exemple #4
0
tmmethodnode *tmreader_method(tmreader *tmr, uint32 serial)
{
    const void *key;
    PLHashNumber hash;

    key = (const void*) serial;
    hash = hash_serial(key);
    return (tmmethodnode*) *PL_HashTableRawLookup(tmr->methods, hash, key);
}
Exemple #5
0
tmcallsite *tmreader_callsite(tmreader *tmr, uint32 serial)
{
    const void *key;
    PLHashNumber hash;

    key = (const void*) serial;
    hash = hash_serial(key);
    return (tmcallsite*) *PL_HashTableRawLookup(tmr->callsites, hash, key);
}
static int32_t* GetCOMPtrCount(void* aPtr)
{
  PLHashEntry** hep = PL_HashTableRawLookup(gSerialNumbers, PLHashNumber(NS_PTR_TO_INT32(aPtr)), aPtr);
  if (hep && *hep) {
    return &((reinterpret_cast<serialNumberRecord*>((*hep)->value))->COMPtrCount);
  } else {
    return nullptr;
  }
}
Exemple #7
0
static int32_t*
GetCOMPtrCount(void* aPtr)
{
  PLHashEntry** hep = PL_HashTableRawLookup(gSerialNumbers,
                                            HashNumber(aPtr),
                                            aPtr);
  if (hep && *hep) {
    return &(static_cast<SerialNumberRecord*>((*hep)->value)->COMPtrCount);
  }
  return nullptr;
}
Exemple #8
0
PRBool ATSUILayoutCache::Get(atsuiLayoutCacheKey *key, ATSUTextLayout *txlayout)
{
	PLHashEntry **hep = PL_HashTableRawLookup(mTable, HashKey(key), key);
	PLHashEntry *he = *hep;
	if( he )
	{
		*txlayout = (ATSUTextLayout)he->value;
		return PR_TRUE;
	}
	return PR_FALSE;
}
Exemple #9
0
PL_HashTableLookup(PLHashTable *ht, const void *key)
{
    PLHashNumber keyHash;
    PLHashEntry *he, **hep;

    keyHash = (*ht->keyHash)(key);
    hep = PL_HashTableRawLookup(ht, keyHash, key);
    if ((he = *hep) != 0) {
        return he->value;
    }
    return 0;
}
Exemple #10
0
static nsNamedVector* GetVector(PLHashTable* table, const void* key)
{
    PLHashNumber hash = _hash_pointer(key);
    PLHashEntry** hep = PL_HashTableRawLookup(table, hash, key);
    PLHashEntry* he = *hep;
    if (he)
        return (nsNamedVector*) he->value;
    nsNamedVector* vec = new nsNamedVector();
    if (vec)
        PL_HashTableRawAdd(table, hep, hash, key, vec);
    return vec;
}
Exemple #11
0
PL_HashTableRemove(PLHashTable *ht, const void *key)
{
    PLHashNumber keyHash;
    PLHashEntry *he, **hep;

    keyHash = (*ht->keyHash)(key);
    hep = PL_HashTableRawLookup(ht, keyHash, key);
    if ((he = *hep) == 0)
        return PR_FALSE;

    /* Hit; remove element */
    PL_HashTableRawRemove(ht, hep, he);
    return PR_TRUE;
}
Exemple #12
0
static intptr_t
GetSerialNumber(void* aPtr, bool aCreate)
{
  PLHashEntry** hep = PL_HashTableRawLookup(gSerialNumbers,
                                            HashNumber(aPtr),
                                            aPtr);
  if (hep && *hep) {
    return static_cast<SerialNumberRecord*>((*hep)->value)->serialNumber;
  } else if (aCreate) {
    SerialNumberRecord* record = new SerialNumberRecord();
    WalkTheStackSavingLocations(record->allocationStack);
    PL_HashTableRawAdd(gSerialNumbers, hep, HashNumber(aPtr),
                       aPtr, static_cast<void*>(record));
    return gNextSerialNumber;
  }
  return 0;
}
static intptr_t GetSerialNumber(void* aPtr, bool aCreate)
{
  PLHashEntry** hep = PL_HashTableRawLookup(gSerialNumbers, PLHashNumber(NS_PTR_TO_INT32(aPtr)), aPtr);
  if (hep && *hep) {
    return reinterpret_cast<serialNumberRecord*>((*hep)->value)->serialNumber;
  }
  else if (aCreate) {
    serialNumberRecord *record = PR_NEW(serialNumberRecord);
    record->serialNumber = ++gNextSerialNumber;
    record->refCount = 0;
    record->COMPtrCount = 0;
    PL_HashTableRawAdd(gSerialNumbers, hep, PLHashNumber(NS_PTR_TO_INT32(aPtr)), aPtr, reinterpret_cast<void*>(record));
    return gNextSerialNumber;
  }
  else {
    return 0;
  }
}
Exemple #14
0
PL_HashTableAdd(PLHashTable *ht, const void *key, void *value)
{
    PLHashNumber keyHash;
    PLHashEntry *he, **hep;

    keyHash = (*ht->keyHash)(key);
    hep = PL_HashTableRawLookup(ht, keyHash, key);
    if ((he = *hep) != 0) {
        /* Hit; see if values match */
        if ((*ht->valueCompare)(he->value, value)) {
            /* key,value pair is already present in table */
            return he;
        }
        if (he->value)
            (*ht->allocOps->freeEntry)(ht->allocPriv, he, HT_FREE_VALUE);
        he->value = value;
        return he;
    }
    return PL_HashTableRawAdd(ht, hep, keyHash, key, value);
}
Exemple #15
0
PL_HashTableRawRemove(PLHashTable *ht, PLHashEntry **hep, PLHashEntry *he)
{
    PRUint32 i, n;
    PLHashEntry *next, **oldbuckets;
    PRSize nb;

    *hep = he->next;
    (*ht->allocOps->freeEntry)(ht->allocPriv, he, HT_FREE_ENTRY);

    /* Shrink table if it's underloaded */
    n = NBUCKETS(ht);
    if (--ht->nentries < UNDERLOADED(n)) {
        oldbuckets = ht->buckets;
        nb = n * sizeof(PLHashEntry*) / 2;
        ht->buckets = (PLHashEntry**)(
            (*ht->allocOps->allocTable)(ht->allocPriv, nb));
        if (!ht->buckets) {
            ht->buckets = oldbuckets;
            return;
        }
        memset(ht->buckets, 0, nb);
#ifdef HASHMETER
        ht->nshrinks++;
#endif
        ht->shift++;

        for (i = 0; i < n; i++) {
            for (he = oldbuckets[i]; he; he = next) {
                next = he->next;
                hep = PL_HashTableRawLookup(ht, he->keyHash, he->key);
                PR_ASSERT(*hep == 0);
                he->next = 0;
                *hep = he;
            }
        }
#ifdef DEBUG
        memset(oldbuckets, 0xDB, n * sizeof oldbuckets[0]);
#endif
        (*ht->allocOps->freeTable)(ht->allocPriv, oldbuckets);
    }
}
Exemple #16
0
static intptr_t
GetSerialNumber(void* aPtr, bool aCreate)
{
  PLHashEntry** hep = PL_HashTableRawLookup(gSerialNumbers,
                                            HashNumber(aPtr),
                                            aPtr);
  if (hep && *hep) {
    MOZ_RELEASE_ASSERT(!aCreate, "If an object already has a serial number, we should be destroying it.");
    return static_cast<SerialNumberRecord*>((*hep)->value)->serialNumber;
  }

  if (!aCreate) {
    return 0;
  }

  SerialNumberRecord* record = new SerialNumberRecord();
  WalkTheStackSavingLocations(record->allocationStack);
  PL_HashTableRawAdd(gSerialNumbers, hep, HashNumber(aPtr),
                     aPtr, static_cast<void*>(record));
  return gNextSerialNumber;
}
Exemple #17
0
int tmreader_eventloop(tmreader *tmr, const char *filename,
                       tmeventhandler eventhandler)
{
    FILE *fp;
    char buf[NS_TRACE_MALLOC_MAGIC_SIZE];
    tmevent event;
    static const char magic[] = NS_TRACE_MALLOC_MAGIC;

    if (strcmp(filename, "-") == 0) {
        fp = stdin;
    } else {
#if defined(XP_WIN32)
        fp = fopen(filename, "rb");
#else
        fp = fopen(filename, "r");
#endif
        if (!fp) {
            fprintf(stderr, "%s: can't open %s: %s.\n",
                    tmr->program, filename, strerror(errno));
            return 0;
        }
    }

    if (read(fileno(fp), buf, sizeof buf) != sizeof buf ||
        strncmp(buf, magic, sizeof buf) != 0) {
        fprintf(stderr, "%s: bad magic string %s at start of %s.\n",
                tmr->program, buf, filename);
        fprintf(stderr, "either the data file is out of date,\nor your tools are out of date.\n");
        return 0;
    }

    /* Read in ticks per second. Used to convert platform specific intervals to time values */
    if (read(fileno(fp), &tmr->ticksPerSec, sizeof tmr->ticksPerSec) != sizeof tmr->ticksPerSec) {
        fprintf(stderr, "%s: Cannot read ticksPerSec. Log file read error.\n",
                tmr->program);
        return 0;
    }
    tmr->ticksPerSec = PR_ntohl(tmr->ticksPerSec);
#ifdef DEBUG_dp
    printf("DEBUG: ticks per sec = %d\n", tmr->ticksPerSec);
#endif
    while (get_tmevent(fp, &event)) {
        switch (event.type) {
          case TM_EVENT_LIBRARY: {
            const void *key;
            PLHashNumber hash;
            PLHashEntry **hep, *he;

            key = (const void*) event.serial;
            hash = hash_serial(key);
            hep = PL_HashTableRawLookup(tmr->libraries, hash, key);
            he = *hep;
            PR_ASSERT(!he);
            if (he) exit(2);

            he = PL_HashTableRawAdd(tmr->libraries, hep, hash, key,
                                    event.u.libname);
            if (!he) {
                perror(tmr->program);
                return -1;
            }
            break;
          }

          case TM_EVENT_FILENAME: {
            const void *key;
            PLHashNumber hash;
            PLHashEntry **hep, *he;

            key = (const void*) event.serial;
            hash = hash_serial(key);
            hep = PL_HashTableRawLookup(tmr->filenames, hash, key);
            he = *hep;
            PR_ASSERT(!he);
            if (he) exit(2);

            he = PL_HashTableRawAdd(tmr->filenames, hep, hash, key,
                                    event.u.srcname);
            if (!he) {
                perror(tmr->program);
                return -1;
            }
            break;
          }

          case TM_EVENT_METHOD: {
            const void *key, *sourcekey;
            PLHashNumber hash, sourcehash;
            PLHashEntry **hep, *he, **sourcehep, *sourcehe;
            char *name, *head, *mark, save;
            tmgraphnode *comp, *lib;
            tmmethodnode *meth;

            key = (const void*) event.serial;
            hash = hash_serial(key);
            hep = PL_HashTableRawLookup(tmr->methods, hash, key);
            he = *hep;
            PR_ASSERT(!he);
            if (he) exit(2);

            name = event.u.method.name;
            he = PL_HashTableRawAdd(tmr->methods, hep, hash, key, name);
            if (!he) {
                perror(tmr->program);
                return -1;
            }
            meth = (tmmethodnode*) he;

            meth->linenumber = event.u.method.linenumber;
            sourcekey = (const void*)event.u.method.filename;
            sourcehash = hash_serial(sourcekey);
            sourcehep = PL_HashTableRawLookup(tmr->filenames, sourcehash, sourcekey);
            sourcehe = *sourcehep;
            meth->sourcefile = filename_name(sourcehe);

            head = name;
            mark = strchr(name, ':');
            if (!mark) {
                mark = name;
                while (*mark != '\0' && *mark == '_')
                    mark++;
                head = mark;
                mark = strchr(head, '_');
                if (!mark) {
                    mark = strchr(head, '+');
                    if (!mark)
                        mark = head + strlen(head);
                }
            }

            save = *mark;
            *mark = '\0';
            hash = PL_HashString(head);
            hep = PL_HashTableRawLookup(tmr->components, hash, head);
            he = *hep;
            if (he) {
                comp = (tmgraphnode*) he;
            } else {
                head = strdup(head);
                if (head) {
                    he = PL_HashTableRawAdd(tmr->components, hep, hash, head,
                                            head);
                }
                if (!he) {
                    perror(tmr->program);
                    return -1;
                }
                comp = (tmgraphnode*) he;

                key = (const void*) event.u.method.library;
                hash = hash_serial(key);
                lib = (tmgraphnode*)
                      *PL_HashTableRawLookup(tmr->libraries, hash, key);
                if (lib) {
                    comp->up = lib;
                    comp->next = lib->down;
                    lib->down = comp;
                }
            }
            *mark = save;

            meth->graphnode.up = comp;
            meth->graphnode.next = comp->down;
            comp->down = &(meth->graphnode);
            break;
          }

          case TM_EVENT_CALLSITE: {
            const void *key, *mkey;
            PLHashNumber hash, mhash;
            PLHashEntry **hep, *he;
            tmcallsite *site, *parent;
            tmmethodnode *meth;

            key = (const void*) event.serial;
            hash = hash_serial(key);
            hep = PL_HashTableRawLookup(tmr->callsites, hash, key);
            he = *hep;

            /* there should not be an entry here! */
            PR_ASSERT(!he);
            if (he) exit(2);

            if (event.u.site.parent == 0) {
                parent = &tmr->calltree_root;
            } else {
                parent = tmreader_callsite(tmr, event.u.site.parent);
                if (!parent) {
                    fprintf(stderr, "%s: no parent for %lu (%lu)!\n",
                            tmr->program, (unsigned long) event.serial,
                            (unsigned long) event.u.site.parent);
                    continue;
                }
            }

            he = PL_HashTableRawAdd(tmr->callsites, hep, hash, key, NULL);
            if (!he) {
                perror(tmr->program);
                return -1;
            }

            site = (tmcallsite*) he;
            site->parent = parent;
            site->siblings = parent->kids;
            parent->kids = site;
            site->kids = NULL;

            mkey = (const void*) event.u.site.method;
            mhash = hash_serial(mkey);
            meth = (tmmethodnode*)
                   *PL_HashTableRawLookup(tmr->methods, mhash, mkey);
            site->method = meth;
            site->offset = event.u.site.offset;
            site->allocs.bytes.direct = site->allocs.bytes.total = 0;
            site->allocs.calls.direct = site->allocs.calls.total = 0;
            site->frees.bytes.direct = site->frees.bytes.total = 0;
            site->frees.calls.direct = site->frees.calls.total = 0;
            break;
          }

          case TM_EVENT_MALLOC:
          case TM_EVENT_CALLOC:
          case TM_EVENT_REALLOC: {
            tmcallsite *site;
            uint32 size, oldsize;
            double delta, sqdelta, sqszdelta = 0;
            tmgraphnode *comp, *lib;
            tmmethodnode *meth;

            site = tmreader_callsite(tmr, event.serial);
            if (!site) {
                fprintf(stderr, "%s: no callsite for '%c' (%lu)!\n",
                        tmr->program, event.type, (unsigned long) event.serial);
                continue;
            }

            size = event.u.alloc.size;
            oldsize = event.u.alloc.oldsize;
            delta = (double)size - (double)oldsize;
            site->allocs.bytes.direct += (unsigned long)delta;
            if (event.type != TM_EVENT_REALLOC)
                site->allocs.calls.direct++;
            meth = site->method;
            if (meth) {
                meth->graphnode.allocs.bytes.direct += (unsigned long)delta;
                sqdelta = delta * delta;
                if (event.type == TM_EVENT_REALLOC) {
                    sqszdelta = ((double)size * size)
                              - ((double)oldsize * oldsize);
                    meth->graphnode.sqsum += sqszdelta;
                } else {
                    meth->graphnode.sqsum += sqdelta;
                    meth->graphnode.allocs.calls.direct++;
                }
                comp = meth->graphnode.up;
                if (comp) {
                    comp->allocs.bytes.direct += (unsigned long)delta;
                    if (event.type == TM_EVENT_REALLOC) {
                        comp->sqsum += sqszdelta;
                    } else {
                        comp->sqsum += sqdelta;
                        comp->allocs.calls.direct++;
                    }
                    lib = comp->up;
                    if (lib) {
                        lib->allocs.bytes.direct += (unsigned long)delta;
                        if (event.type == TM_EVENT_REALLOC) {
                            lib->sqsum += sqszdelta;
                        } else {
                            lib->sqsum += sqdelta;
                            lib->allocs.calls.direct++;
                        }
                    }
                }
            }
            break;
          }

          case TM_EVENT_FREE: {
            tmcallsite *site;
            uint32 size;
            tmgraphnode *comp, *lib;
            tmmethodnode *meth;

            site = tmreader_callsite(tmr, event.serial);
            if (!site) {
                fprintf(stderr, "%s: no callsite for '%c' (%lu)!\n",
                        tmr->program, event.type, (unsigned long) event.serial);
                continue;
            }
            size = event.u.alloc.size;
            site->frees.bytes.direct += size;
            site->frees.calls.direct++;
            meth = site->method;
            if (meth) {
                meth->graphnode.frees.bytes.direct += size;
                meth->graphnode.frees.calls.direct++;
                comp = meth->graphnode.up;
                if (comp) {
                    comp->frees.bytes.direct += size;
                    comp->frees.calls.direct++;
                    lib = comp->up;
                    if (lib) {
                        lib->frees.bytes.direct += size;
                        lib->frees.calls.direct++;
                    }
                }
            }
            break;
          }

          case TM_EVENT_STATS:
            break;
        }

        eventhandler(tmr, &event);
    }

    return 1;
}