Bug 948621 (part 1) - DMD: Handle arbitrary PC values in stack frames. r=iacobcatalin.
authorNicholas Nethercote <nnethercote@mozilla.com>
Sun, 15 Dec 2013 13:47:11 -0800
changeset 160546 8a254244f3db007aea4b9b89958a0be2a35de789
parent 160545 a87ddfa1c01ef6004857e5b1c203ee0f77c88221
child 160547 4afced469f9d348b47fdce694327bf6f2778b9ae
push id25836
push userphilringnalda@gmail.com
push dateMon, 16 Dec 2013 01:58:54 +0000
treeherdermozilla-central@f8fea5ea69a1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersiacobcatalin
bugs948621
milestone29.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 948621 (part 1) - DMD: Handle arbitrary PC values in stack frames. r=iacobcatalin. DONTBUILD because NPOTB
memory/replace/dmd/DMD.cpp
--- a/memory/replace/dmd/DMD.cpp
+++ b/memory/replace/dmd/DMD.cpp
@@ -595,28 +595,27 @@ class LocationService
 
   typedef js::HashSet<const char*, StringHasher, InfallibleAllocPolicy>
           StringTable;
 
   StringTable mLibraryStrings;
 
   struct Entry
   {
-    static const void* const kUnused;
-
-    const void* mPc;        // if mPc==kUnused, the entry is unused
+    const void* mPc;
     char*       mFunction;  // owned by the Entry;  may be null
     const char* mLibrary;   // owned by mLibraryStrings;  never null
                             //   in a non-empty entry is in use
     ptrdiff_t   mLOffset;
     char*       mFileName;  // owned by the Entry; may be null
-    unsigned long mLineNo;
+    uint32_t    mLineNo:31;
+    uint32_t    mInUse:1;   // is the entry used?
 
     Entry()
-      : mPc(kUnused), mFunction(nullptr), mLibrary(nullptr), mLOffset(0), mFileName(nullptr), mLineNo(0)
+      : mPc(0), mFunction(nullptr), mLibrary(nullptr), mLOffset(0), mFileName(nullptr), mLineNo(0), mInUse(0)
     {}
 
     ~Entry()
     {
       // We don't free mLibrary because it's externally owned.
       InfallibleAllocPolicy::free_(mFunction);
       InfallibleAllocPolicy::free_(mFileName);
     }
@@ -634,16 +633,18 @@ class LocationService
       InfallibleAllocPolicy::free_(mFileName);
       mFileName =
         !aFileName[0] ? nullptr : InfallibleAllocPolicy::strdup_(aFileName);
 
 
       mLibrary = aLibrary;
       mLOffset = aLOffset;
       mLineNo = aLineNo;
+
+      mInUse = 1;
     }
 
     size_t SizeOfExcludingThis() {
       // Don't measure mLibrary because it's externally owned.
       return MallocSizeOf(mFunction) + MallocSizeOf(mFileName);
     }
   };
 
@@ -670,18 +671,17 @@ public:
   void WriteLocation(const Writer& aWriter, const void* aPc)
   {
     MOZ_ASSERT(gStateLock->IsLocked());
 
     uint32_t index = HashGeneric(aPc) & kMask;
     MOZ_ASSERT(index < kNumEntries);
     Entry& entry = mEntries[index];
 
-    MOZ_ASSERT(aPc != Entry::kUnused);
-    if (entry.mPc != aPc) {
+    if (!entry.mInUse || entry.mPc != aPc) {
       mNumCacheMisses++;
 
       // NS_DescribeCodeAddress can (on Linux) acquire a lock inside
       // the shared library loader.  Another thread might call malloc
       // while holding that lock (when loading a shared library).  So
       // we have to exit gStateLock around this call.  For details, see
       // https://bugzilla.mozilla.org/show_bug.cgi?id=363334#c3
       nsCodeAddressDetails details;
@@ -748,31 +748,27 @@ public:
   }
 
   size_t CacheCapacity() const { return kNumEntries; }
 
   size_t CacheCount() const
   {
     size_t n = 0;
     for (size_t i = 0; i < kNumEntries; i++) {
-      if (mEntries[i].mPc != Entry::kUnused) {
+      if (mEntries[i].mInUse) {
         n++;
       }
     }
     return n;
   }
 
   size_t NumCacheHits()   const { return mNumCacheHits; }
   size_t NumCacheMisses() const { return mNumCacheMisses; }
 };
 
-// We can't use 0 because that sometimes shows up as a PC in stack traces.
-const void* const LocationService::Entry::kUnused =
-  reinterpret_cast<const void* const>(intptr_t(-1));
-
 //---------------------------------------------------------------------------
 // Stack traces
 //---------------------------------------------------------------------------
 
 class StackTrace
 {
 public:
   static const uint32_t MaxFrames = 24;