Bug 412859. Some code to dump the contents of the textrun word cache. debug only. r=pavlov
authorroc+@cs.cmu.edu
Sun, 20 Jan 2008 17:23:50 -0800
changeset 10484 d17f36435df4bf15caa73faf67dd73bd5a2edf79
parent 10483 01c6f17849d73ab020ab0c92288686e1afd12957
child 10485 f5c8286b2966b1b27a5a6a868113369e67e4ff51
push id1
push userbsmedberg@mozilla.com
push dateThu, 20 Mar 2008 16:49:24 +0000
treeherderautoland@61007906a1f8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspavlov
bugs412859
milestone1.9b3pre
Bug 412859. Some code to dump the contents of the textrun word cache. debug only. r=pavlov
gfx/thebes/public/gfxFont.h
gfx/thebes/src/gfxFont.cpp
gfx/thebes/src/gfxTextRunWordCache.cpp
--- a/gfx/thebes/public/gfxFont.h
+++ b/gfx/thebes/public/gfxFont.h
@@ -47,16 +47,20 @@
 #include "nsTHashtable.h"
 #include "nsHashKeys.h"
 #include "gfxSkipChars.h"
 #include "gfxRect.h"
 #include "nsExpirationTracker.h"
 #include "nsMathUtils.h"
 #include "nsBidiUtils.h"
 
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
 class gfxContext;
 class gfxTextRun;
 class nsIAtom;
 class gfxFont;
 class gfxFontGroup;
 
 #define FONT_STYLE_NORMAL              0
 #define FONT_STYLE_ITALIC              1
@@ -1255,16 +1259,18 @@ public:
         
         PRPackedBool mPartIsStartOfLigature;
         PRPackedBool mPartIsEndOfLigature;
     };
 
 #ifdef DEBUG
     // number of entries referencing this textrun in the gfxTextRunWordCache
     PRUint32 mCachedWords;
+    
+    void Dump(FILE* aOutput);
 #endif
 
 protected:
     // Allocates extra space for the CompressedGlyph array and the text
     // (if needed)
     void *operator new(size_t aSize, PRUint32 aLength, PRUint32 aFlags);
 
     /**
--- a/gfx/thebes/src/gfxFont.cpp
+++ b/gfx/thebes/src/gfxFont.cpp
@@ -1974,8 +1974,41 @@ gfxTextRun::FetchGlyphExtents(gfxContext
 #endif
                         font->SetupGlyphExtents(aRefContext, glyphIndex, PR_TRUE, extents);
                     }
                 }
             }
         }
     }
 }
+
+#ifdef DEBUG
+void
+gfxTextRun::Dump(FILE* aOutput) {
+    if (!aOutput) {
+        aOutput = stdout;
+    }
+
+    PRUint32 i;
+    fputc('"', aOutput);
+    for (i = 0; i < mCharacterCount; ++i) {
+        PRUnichar ch = GetChar(i);
+        if (ch >= 32 && ch < 128) {
+            fputc(ch, aOutput);
+        } else {
+            fprintf(aOutput, "\\u%4x", ch);
+        }
+    }
+    fputs("\" [", aOutput);
+    for (i = 0; i < mGlyphRuns.Length(); ++i) {
+        if (i > 0) {
+            fputc(',', aOutput);
+        }
+        gfxFont* font = mGlyphRuns[i].mFont;
+        const gfxFontStyle* style = font->GetStyle();
+        NS_ConvertUTF16toUTF8 fontName(font->GetName());
+        fprintf(aOutput, "%d: %s %f/%d/%d/%s", mGlyphRuns[i].mCharacterOffset,
+                fontName.get(), style->size,
+                style->weight, style->style, style->langGroup.get());
+    }
+    fputc(']', aOutput);
+}
+#endif
--- a/gfx/thebes/src/gfxTextRunWordCache.cpp
+++ b/gfx/thebes/src/gfxTextRunWordCache.cpp
@@ -32,16 +32,20 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "gfxTextRunWordCache.h"
 
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
 /**
  * Cache individual "words" (strings delimited by white-space or white-space-like
  * characters that don't involve kerning or ligatures) in textruns.
   */
 class TextRunWordCache {
 public:
     TextRunWordCache() {
         mCache.Init(100);
@@ -78,16 +82,20 @@ public:
                             PRUint32 aFlags);
 
     /**
      * Remove a textrun from the cache. This must be called before aTextRun
      * is deleted! The text in the textrun must still be valid.
      */
     void RemoveTextRun(gfxTextRun *aTextRun);
 
+#ifdef DEBUG
+    void Dump();
+#endif
+
 protected:
     struct CacheHashKey {
         void        *mFontOrGroup;
         const void  *mString;
         PRUint32     mLength;
         PRUint32     mAppUnitsPerDevUnit;
         PRUint32     mStringHash;
         PRPackedBool mIsDoubleByteText;
@@ -153,16 +161,20 @@ protected:
     void FinishTextRun(gfxTextRun *aTextRun, gfxTextRun *aNewRun,
                        gfxContext *aContext,
                        const nsTArray<DeferredWord>& aDeferredWords,
                        PRBool aSuccessful);
     void RemoveWord(gfxTextRun *aTextRun, PRUint32 aStart,
                     PRUint32 aEnd, PRUint32 aHash);    
 
     nsTHashtable<CacheHashEntry> mCache;
+    
+#ifdef DEBUG
+    static PLDHashOperator PR_CALLBACK CacheDumpEntry(CacheHashEntry* aEntry, void* userArg);
+#endif
 };
 
 static PRLogModuleInfo *gWordCacheLog = PR_NewLogModule("wordCache");
 
 static inline PRUint32
 HashMix(PRUint32 aHash, PRUnichar aCh)
 {
     return (aHash >> 28) ^ (aHash << 4) ^ aCh;
@@ -655,16 +667,38 @@ TextRunWordCache::CacheHashEntry::KeyEqu
 PLDHashNumber
 TextRunWordCache::CacheHashEntry::HashKey(const KeyTypePointer aKey)
 {
     return aKey->mStringHash + (long)aKey->mFontOrGroup + aKey->mAppUnitsPerDevUnit +
         aKey->mIsDoubleByteText + aKey->mIsRTL*2 + aKey->mEnabledOptionalLigatures*4 +
         aKey->mOptimizeSpeed*8;
 }
 
+#ifdef DEBUG
+PLDHashOperator PR_CALLBACK
+TextRunWordCache::CacheDumpEntry(CacheHashEntry* aEntry, void* userArg)
+{
+    FILE* output = static_cast<FILE*>(userArg);
+    if (!aEntry->mTextRun) {
+        fprintf(output, "<EMPTY>\n");
+        return PL_DHASH_NEXT;
+    }
+    fprintf(output, "Word at %x:%d => ", aEntry->mTextRun, aEntry->mWordOffset);
+    aEntry->mTextRun->Dump(output);
+    fprintf(output, " (hashed by %s)\n", aEntry->mHashedByFont ? "font" : "fontgroup");
+    return PL_DHASH_NEXT;
+}
+
+void
+TextRunWordCache::Dump()
+{
+    mCache.EnumerateEntries(CacheDumpEntry, stdout);
+}
+#endif
+
 static TextRunWordCache *gTextRunWordCache = nsnull;
 
 nsresult
 gfxTextRunWordCache::Init()
 {
     gTextRunWordCache = new TextRunWordCache();
     return gTextRunWordCache ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
 }