Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Typedefs | Functions | Variables
nsAtomTable.cpp File Reference
#include "nsAtomTable.h"
#include "nsStaticAtom.h"
#include "nsString.h"
#include "nsReadableUtils.h"
#include "nsCRT.h"
#include "pldhash.h"
#include "prenv.h"
#include "nsVoidArray.h"
#include "plarena.h"

Go to the source code of this file.

Classes

class  nsStaticAtomWrapper
struct  AtomTableEntry

Defines

#define PL_ARENA_CONST_ALIGN_MASK   3

Typedefs

typedef unsigned long PtrBits

Functions

 AtomTableGetKey (PLDHashTable *table, PLDHashEntryHdr *entry)
 AtomTableMatchKey (PLDHashTable *table, const PLDHashEntryHdr *entry, const void *key)
 AtomTableClearEntry (PLDHashTable *table, PLDHashEntryHdr *entry)
static void PromoteToPermanent (AtomImpl *aAtom)
void NS_PurgeAtomTable ()
 NS_IMETHODIMP_ (nsrefcnt) PermanentAtomImpl
NS_COM nsIAtomNS_NewAtom (const char *isolatin1)
 Find an atom that matches the given UTF-8 string.
NS_COM nsIAtomNS_NewPermanentAtom (const char *isolatin1)
static nsStaticAtomWrapperWrapStaticAtom (const nsStaticAtom *aAtom)
static AtomTableEntryGetAtomHashEntry (const char *aString)
NS_COM nsresult NS_RegisterStaticAtoms (const nsStaticAtom *aAtoms, PRUint32 aAtomCount)
NS_COM nsIAtomNS_NewAtom (const nsAString &aString)
 Find an atom that matches the given UTF-16 string.
NS_COM nsIAtomNS_NewAtom (const nsACString &aString)
 Find an atom that matches the given UTF-8 string.
NS_COM nsIAtomNS_NewPermanentAtom (const nsAString &aString)
NS_COM nsIAtomNS_NewPermanentAtom (const nsACString &aString)
NS_COM nsIAtomNS_NewAtom (const PRUnichar *str)
 Find an atom that matches the given UTF-16 string.
NS_COM nsIAtomNS_NewPermanentAtom (const PRUnichar *str)
NS_COM nsrefcnt NS_GetNumberOfAtoms (void)
 Return a count of the total number of atoms currently alive in the system.

Variables

static PLDHashTable gAtomTable
 The shared hash table for atom lookups.
static PLArenaPoolgStaticAtomArena = 0
static const PLDHashTableOps AtomTableOps

Define Documentation

Definition at line 48 of file nsAtomTable.cpp.


Typedef Documentation

typedef unsigned long PtrBits

Definition at line 99 of file nsAtomTable.cpp.


Function Documentation

AtomTableClearEntry ( PLDHashTable table,
PLDHashEntryHdr entry 
)

Definition at line 188 of file nsAtomTable.cpp.

{
  AtomTableEntry *he = NS_STATIC_CAST(AtomTableEntry*, entry);
  
  he->keyHash = 0;

  if (!he->IsStaticAtom()) {
    AtomImpl *atom = he->GetAtomImpl();
    // Normal |AtomImpl| atoms are deleted when their refcount hits 0, and
    // they then remove themselves from the table.  In other words, they
    // are owned by the callers who own references to them.
    // |PermanentAtomImpl| permanent atoms ignore their refcount and are
    // deleted when they are removed from the table at table destruction.
    // In other words, they are owned by the atom table.
    if (atom->IsPermanent())
      delete NS_STATIC_CAST(PermanentAtomImpl*, atom);
  }
  else {
    he->GetStaticAtomWrapper()->~nsStaticAtomWrapper();
  }
  
  he->ClearAtom();
}

Here is the call graph for this function:

AtomTableGetKey ( PLDHashTable table,
PLDHashEntryHdr entry 
)

Definition at line 170 of file nsAtomTable.cpp.

{
  AtomTableEntry *he = NS_STATIC_CAST(AtomTableEntry*, entry);
  NS_ASSERTION(he->HasValue(), "Empty atom. how did that happen?");
  return he->get();
}

Here is the call graph for this function:

AtomTableMatchKey ( PLDHashTable table,
const PLDHashEntryHdr entry,
const void key 
)

Definition at line 178 of file nsAtomTable.cpp.

{
  const AtomTableEntry *he = NS_STATIC_CAST(const AtomTableEntry*, entry);
  const char* keyStr = NS_STATIC_CAST(const char*, key);
  return nsCRT::strcmp(keyStr, he->get()) == 0;
}

Here is the call graph for this function:

static AtomTableEntry* GetAtomHashEntry ( const char *  aString) [static]

Definition at line 494 of file nsAtomTable.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

Return a count of the total number of atoms currently alive in the system.

Definition at line 623 of file nsAtomTable.cpp.

{
  return gAtomTable.entryCount;
}

Here is the caller graph for this function:

Definition at line 320 of file nsAtomTable.cpp.

{
  return 2;
}
NS_COM nsIAtom* NS_NewAtom ( const char *  aUTF8String)

Find an atom that matches the given UTF-8 string.

The string is assumed to be zero terminated.

Definition at line 464 of file nsAtomTable.cpp.

{
  return NS_NewAtom(nsDependentCString(isolatin1));
}

Here is the call graph for this function:

Here is the caller graph for this function:

NS_COM nsIAtom* NS_NewAtom ( const nsAString &  aString)

Find an atom that matches the given UTF-16 string.

Definition at line 550 of file nsAtomTable.cpp.

{
  NS_ConvertUCS2toUTF8 utf8String(aString);

  return NS_NewAtom(utf8String);
}

Here is the call graph for this function:

NS_COM nsIAtom* NS_NewAtom ( const nsACString &  aString)

Find an atom that matches the given UTF-8 string.

Definition at line 559 of file nsAtomTable.cpp.

{
  AtomTableEntry *he = GetAtomHashEntry(PromiseFlatCString(aString).get());

  if (he->HasValue())
    return he->GetAtom();

  AtomImpl* atom = new (aString) AtomImpl();
  he->SetAtomImpl(atom);
  if (!atom) {
    PL_DHashTableRawRemove(&gAtomTable, he);
    return nsnull;
  }

  NS_ADDREF(atom);
  return atom;
}

Here is the call graph for this function:

NS_COM nsIAtom* NS_NewAtom ( const PRUnichar aUTF16String)

Find an atom that matches the given UTF-16 string.

The string is assumed to be zero terminated.

Definition at line 613 of file nsAtomTable.cpp.

Here is the call graph for this function:

NS_COM nsIAtom* NS_NewPermanentAtom ( const char *  isolatin1)

Definition at line 469 of file nsAtomTable.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

NS_COM nsIAtom* NS_NewPermanentAtom ( const nsAString &  aString)

Definition at line 577 of file nsAtomTable.cpp.

Here is the call graph for this function:

NS_COM nsIAtom* NS_NewPermanentAtom ( const nsACString &  aString)

Definition at line 583 of file nsAtomTable.cpp.

{
  AtomTableEntry *he = GetAtomHashEntry(PromiseFlatCString(aString).get());

  if (he->HasValue() && he->IsStaticAtom())
    return he->GetStaticAtomWrapper();
  
  // either there is no atom and we'll create an AtomImpl,
  // or there is an existing AtomImpl
  AtomImpl* atom = he->GetAtomImpl();
  
  if (atom) {
    // ensure that it's permanent
    if (!atom->IsPermanent()) {
      PromoteToPermanent(atom);
    }
  } else {
    // otherwise, make a new atom
    atom = new (aString) PermanentAtomImpl();
    he->SetAtomImpl(atom);
    if ( !atom ) {
      PL_DHashTableRawRemove(&gAtomTable, he);
      return nsnull;
    }
  }

  NS_ADDREF(atom);
  return atom;
}

Here is the call graph for this function:

Definition at line 618 of file nsAtomTable.cpp.

Here is the call graph for this function:

Definition at line 263 of file nsAtomTable.cpp.

{
  if (gAtomTable.ops) {
#ifdef DEBUG
    if (PR_GetEnv("MOZ_DUMP_ATOM_LEAKS")) {
      PRUint32 leaked = 0;
      printf("*** %d atoms still exist (including permanent):\n",
             gAtomTable.entryCount);
      PL_DHashTableEnumerate(&gAtomTable, DumpAtomLeaks, &leaked);
      printf("*** %u non-permanent atoms leaked\n", leaked);
    }
#endif
    PL_DHashTableFinish(&gAtomTable);
    gAtomTable.entryCount = 0;
    gAtomTable.ops = nsnull;

    if (gStaticAtomArena) {
      PL_FinishArenaPool(gStaticAtomArena);
      delete gStaticAtomArena;
      gStaticAtomArena = nsnull;
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 509 of file nsAtomTable.cpp.

{
  // this does two things:
  // 1) wraps each static atom in a wrapper, if necessary
  // 2) initializes the address pointed to by each mAtom slot
  
  for (PRUint32 i=0; i<aAtomCount; i++) {
    NS_ASSERTION(nsCRT::IsAscii(aAtoms[i].mString),
                 "Static atoms must be ASCII!");
    AtomTableEntry *he =
      GetAtomHashEntry(aAtoms[i].mString);
    
    if (he->HasValue() && aAtoms[i].mAtom) {
      // there already is an atom with this name in the table.. but we
      // still have to update mAtom
      if (!he->IsStaticAtom() && !he->GetAtomImpl()->IsPermanent()) {
        // since we wanted to create a static atom but there is
        // already one there, we convert it to a non-refcounting
        // permanent atom
        PromoteToPermanent(he->GetAtomImpl());
      }
      
      // and now, if the consumer wants to remember this value in a
      // slot, we do so
      if (aAtoms[i].mAtom)
        *aAtoms[i].mAtom = he->GetAtom();
    }
    
    else {
      nsStaticAtomWrapper* atom = WrapStaticAtom(&aAtoms[i]);
      NS_ASSERTION(atom, "Failed to wrap static atom");

      // but even if atom is null, no real difference in code..
      he->SetStaticAtomWrapper(atom);
      if (aAtoms[i].mAtom)
        *aAtoms[i].mAtom = atom;
    }
  }
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void PromoteToPermanent ( AtomImpl aAtom) [inline, static]

Definition at line 250 of file nsAtomTable.cpp.

{
#ifdef NS_BUILD_REFCNT_LOGGING
  {
    nsrefcnt refcount = aAtom->GetRefCount();
    do {
      NS_LOG_RELEASE(aAtom, --refcount, "AtomImpl");
    } while (refcount);
  }
#endif
  aAtom = new (aAtom) PermanentAtomImpl();
}

Here is the call graph for this function:

Here is the caller graph for this function:

static nsStaticAtomWrapper* WrapStaticAtom ( const nsStaticAtom aAtom) [static]

Definition at line 475 of file nsAtomTable.cpp.

{
  if (!gStaticAtomArena) {
    gStaticAtomArena = new PLArenaPool;
    if (!gStaticAtomArena)
      return nsnull;
    
    PL_INIT_ARENA_POOL(gStaticAtomArena, "nsStaticAtomArena", 4096);
  }
  
  void* mem;
  PL_ARENA_ALLOCATE(mem, gStaticAtomArena, sizeof(nsStaticAtom));
  
  nsStaticAtomWrapper* wrapper =
    new (mem) nsStaticAtomWrapper(aAtom);
  
  return wrapper;
}

Here is the caller graph for this function:


Variable Documentation

The shared hash table for atom lookups.

XXX This should be manipulated in a threadsafe way or we should make sure it's only manipulated from the main thread. Probably the latter is better, since the former would hurt performance.

If |gAtomTable.ops| is 0, then the table is uninitialized.

Definition at line 51 of file nsAtomTable.cpp.

Definition at line 66 of file nsAtomTable.cpp.