Try to fix intermittent refcount assertions in the presence of more than one thread. Bug 587277 - TM: ExecutablePool release race. r=sayrer
authorChris Leary <cdleary@mozilla.com>
Sat, 14 Aug 2010 00:34:14 -0700
changeset 50646 9825a728b2cb340c34b663944f28725f61ef1531
parent 50645 a9c461fb78e21ebaf38ea0886b84eab0233706d6
child 50647 07822d2a6758a1bf429370de1935089a28487015
push idunknown
push userunknown
push dateunknown
reviewerssayrer
bugs587277
milestone2.0b4pre
Try to fix intermittent refcount assertions in the presence of more than one thread. Bug 587277 - TM: ExecutablePool release race. r=sayrer
js/src/assembler/jit/ExecutableAllocator.h
--- a/js/src/assembler/jit/ExecutableAllocator.h
+++ b/js/src/assembler/jit/ExecutableAllocator.h
@@ -23,21 +23,22 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
 #ifndef ExecutableAllocator_h
 #define ExecutableAllocator_h
 
 #include <stddef.h> // for ptrdiff_t
 #include <limits>
-#include <wtf/Assertions.h>
+#include "assembler/wtf/Assertions.h"
 
 #include "jsapi.h"
 #include "jsprvtd.h"
 #include "jsvector.h"
+#include "jslock.h"
 
 #if WTF_PLATFORM_IPHONE
 #include <libkern/OSCacheControl.h>
 #include <sys/mman.h>
 #endif
 
 #if WTF_PLATFORM_SYMBIAN
 #include <e32std.h>
@@ -75,17 +76,17 @@ namespace JSC {
 inline size_t roundUpAllocationSize(size_t request, size_t granularity)
 {
     if ((std::numeric_limits<size_t>::max() - granularity) <= request)
         CRASH(); // Allocation is too large
     
     // Round up to next page boundary
     size_t size = request + (granularity - 1);
     size = size & ~(granularity - 1);
-    ASSERT(size >= request);
+    JS_ASSERT(size >= request);
     return size;
 }
 
 }
 
 #if ENABLE_ASSEMBLER
 
 namespace JSC {
@@ -99,38 +100,38 @@ private:
         size_t size;
 #if WTF_PLATFORM_SYMBIAN
         RChunk* chunk;
 #endif
     };
     typedef js::Vector<Allocation, 2 ,js::SystemAllocPolicy > AllocationList;
 
     // Reference count for automatic reclamation.
-    unsigned m_refCount;
+    jsrefcount m_refCount;
 
 public:
       // It should be impossible for us to roll over, because only small
       // pools have multiple holders, and they have one holder per chunk
       // of generated code, and they only hold 16KB or so of code.
-      void addRef() { ++m_refCount; }
+      void addRef() { JS_ATOMIC_INCREMENT(&m_refCount); }
       void release() { 
-	  ASSERT(m_refCount != 0);
-	  if (--m_refCount == 0) 
+	  JS_ASSERT(m_refCount != 0);
+	  if (JS_ATOMIC_DECREMENT(&m_refCount) == 0) 
 	      delete this; 
       }
 
     //static PassRefPtr<ExecutablePool> create(size_t n)
     static ExecutablePool* create(size_t n)
     {
         return new ExecutablePool(n);
     }
 
     void* alloc(size_t n)
     {
-        ASSERT(m_freePtr <= m_end);
+        JS_ASSERT(m_freePtr <= m_end);
 
         // Round 'n' up to a multiple of word size; if all allocations are of
         // word sized quantities, then all subsequent allocations will be aligned.
         n = roundUpAllocationSize(n, sizeof(void*));
 
         if (static_cast<ptrdiff_t>(n) < (m_end - m_freePtr)) {
             void* result = m_freePtr;
             m_freePtr += n;
@@ -334,17 +335,17 @@ inline ExecutablePool::ExecutablePool(si
 inline void* ExecutablePool::poolAllocate(size_t n)
 {
     size_t allocSize = roundUpAllocationSize(n, JIT_ALLOCATOR_PAGE_SIZE);
     
     Allocation result = systemAlloc(allocSize);
     if (!result.pages)
         CRASH(); // Failed to allocate
     
-    ASSERT(m_end >= m_freePtr);
+    JS_ASSERT(m_end >= m_freePtr);
     if ((allocSize - n) > static_cast<size_t>(m_end - m_freePtr)) {
         // Replace allocation pool
         m_freePtr = result.pages + n;
         m_end = result.pages + allocSize;
     }
 
     m_pools.append(result);
     return result.pages;