Reviewed by Maciej.

        Make JSGlobalData per-thread.

        No change on SunSpider total.

        * wtf/ThreadSpecific.h: Re-enabled the actual implementation.

        * kjs/JSGlobalObject.cpp:
        (KJS::JSGlobalObject::~JSGlobalObject): Re-added a JSLock-related assertion. We'll probably
        want to preserve these somehow to keep legacy behavior in working condition.
        (KJS::JSGlobalObject::init): Initialize globalData pointer earlier, so that it is ready
        when updating JSGlobalObject linked list.

        * kjs/JSGlobalObject.h: (KJS::JSGlobalObject::head): Changed head() to be non-static, and
        to use JSGlobalData associated with the current object.

        * kjs/InitializeThreading.cpp: (KJS::initializeThreadingOnce): Removed a no longer needed
        Heap::registerAsMainThread() call.

        * kjs/JSGlobalData.h: Removed a lying lie comment - parserObjectExtraRefCounts is not
        transient, and while newParserObjects may conceptually be such, there is still some node
        manipulation going on outside Parser::parse which touches it.

        * kjs/JSGlobalData.cpp:
        (KJS::JSGlobalData::~JSGlobalData): Delete recently added members.
        (KJS::JSGlobalData::sharedInstance): Actually use a separate instance.

        * kjs/collector.cpp:
        (KJS::Heap::Heap):
        (KJS::Heap::~Heap): Added a destructor, which unconditionally deletes everything.
        (KJS::Heap::sweep): Removed code related to "collect on main thread only" logic.
        (KJS::Heap::collect): Ditto.
        (KJS::Heap::globalObjectCount): Explicitly use per-thread instance of JSGlobalObject linked
        list now that JSGlobalObject::head() is not static. Curently, WebCoreStatistics methods only
        work with the main thread currently anyway.
        (KJS::Heap::protectedGlobalObjectCount): Ditto.

        * kjs/collector.h: Removed code related to "collect on main thread only" logic.

        * JavaScriptCore.exp: Removed Heap::collectOnMainThreadOnly.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@34810 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JavaScriptCore/kjs/collector.cpp b/JavaScriptCore/kjs/collector.cpp
index 206266d..152d43c 100644
--- a/JavaScriptCore/kjs/collector.cpp
+++ b/JavaScriptCore/kjs/collector.cpp
@@ -87,14 +87,29 @@
 // a PIC branch in Mach-O binaries, see <rdar://problem/5971391>.
 #define MIN_ARRAY_SIZE (static_cast<size_t>(14))
 
+static void freeHeap(CollectorHeap*);
+
 Heap::Heap()
-    : mainThreadOnlyObjectCount(0)
-    , m_markListSet(0)
+    : m_markListSet(0)
 {
     memset(&primaryHeap, 0, sizeof(CollectorHeap));
     memset(&numberHeap, 0, sizeof(CollectorHeap));
 }
 
+Heap::~Heap()
+{
+    JSLock lock;
+
+    delete m_markListSet;
+    sweep<PrimaryHeap>();
+    // No need to sweep number heap, because the JSNumber destructor doesn't do anything.
+
+    ASSERT(!primaryHeap.numLiveObjects);
+
+    freeHeap(&primaryHeap);
+    freeHeap(&numberHeap);
+}
+
 static NEVER_INLINE CollectorBlock* allocateBlock()
 {
 #if PLATFORM(DARWIN)    
@@ -151,6 +166,15 @@
 #endif
 }
 
+static void freeHeap(CollectorHeap* heap)
+{
+    for (size_t i = 0; i < heap->usedBlocks; ++i)
+        if (heap->blocks[i])
+            freeBlock(heap->blocks[i]);
+    fastFree(heap->blocks);
+    memset(heap, 0, sizeof(CollectorHeap));
+}
+
 void Heap::recordExtraCost(size_t cost)
 {
     // Our frequency of garbage collection tries to balance memory use against speed
@@ -367,30 +391,6 @@
 }
 
 #if USE(MULTIPLE_THREADS)
-static pthread_t mainThread;
-#endif
-
-void Heap::registerAsMainThread()
-{
-#if USE(MULTIPLE_THREADS)
-    mainThread = pthread_self();
-#endif
-}
-
-static inline bool onMainThread()
-{
-#if USE(MULTIPLE_THREADS)
-#if PLATFORM(DARWIN)
-    return pthread_main_np();
-#else
-    return !!pthread_equal(pthread_self(), mainThread);
-#endif
-#else
-    return true;
-#endif
-}
-
-#if USE(MULTIPLE_THREADS)
 
 #if PLATFORM(DARWIN)
 typedef mach_port_t PlatformThread;
@@ -770,20 +770,6 @@
     protectedValues.remove(k->asCell());
 }
 
-void Heap::collectOnMainThreadOnly(JSValue* value)
-{
-    ASSERT(value);
-    ASSERT(JSLock::lockCount() > 0);
-    ASSERT(JSLock::currentThreadIsHoldingLock());
-
-    if (JSImmediate::isImmediate(value))
-        return;
-
-    JSCell* cell = value->asCell();
-    cellBlock(cell)->collectOnMainThreadOnly.set(cellOffset(cell));
-    ++mainThreadOnlyObjectCount;
-}
-
 Heap* Heap::heap(const JSValue* v)
 {
     if (JSImmediate::isImmediate(v))
@@ -801,54 +787,11 @@
     }
 }
 
-void Heap::markMainThreadOnlyObjects()
-{
-#if USE(MULTIPLE_THREADS)
-    ASSERT(!onMainThread());
-#endif
-
-    // Optimization for clients that never register "main thread only" objects.
-    if (!mainThreadOnlyObjectCount)
-        return;
-
-    // FIXME: We can optimize this marking algorithm by keeping an exact set of 
-    // "main thread only" objects when the "main thread only" object count is 
-    // small. We don't want to keep an exact set all the time, because WebCore 
-    // tends to create lots of "main thread only" objects, and all that set 
-    // thrashing can be expensive.
-    
-    size_t count = 0;
-    
-    // We don't look at the numberHeap as primitive values can never be marked as main thread only
-    for (size_t block = 0; block < primaryHeap.usedBlocks; block++) {
-        ASSERT(count < mainThreadOnlyObjectCount);
-        
-        CollectorBlock* curBlock = primaryHeap.blocks[block];
-        size_t minimumCellsToProcess = curBlock->usedCells;
-        for (size_t i = 0; (i < minimumCellsToProcess) & (i < CELLS_PER_BLOCK); i++) {
-            CollectorCell* cell = curBlock->cells + i;
-            if (cell->u.freeCell.zeroIfFree == 0)
-                ++minimumCellsToProcess;
-            else {
-                if (curBlock->collectOnMainThreadOnly.get(i)) {
-                    if (!curBlock->marked.get(i)) {
-                        JSCell* imp = reinterpret_cast<JSCell*>(cell);
-                        imp->mark();
-                    }
-                    if (++count == mainThreadOnlyObjectCount)
-                        return;
-                }
-            }
-        }
-    }
-}
-
-template <Heap::HeapType heapType> size_t Heap::sweep(bool currentThreadIsMainThread)
+template <Heap::HeapType heapType> size_t Heap::sweep()
 {
     typedef typename HeapConstants<heapType>::Block Block;
     typedef typename HeapConstants<heapType>::Cell Cell;
 
-    UNUSED_PARAM(currentThreadIsMainThread); // currentThreadIsMainThread is only used in ASSERTs
     // SWEEP: delete everything with a zero refcount (garbage) and unmark everything else
     CollectorHeap& heap = heapType == Heap::PrimaryHeap ? primaryHeap : numberHeap;
     
@@ -875,11 +818,6 @@
                         if (cell->u.freeCell.zeroIfFree == 0)
                             continue;
                         
-                        ASSERT(currentThreadIsMainThread || !curBlock->collectOnMainThreadOnly.get(i));
-                        if (curBlock->collectOnMainThreadOnly.get(i)) {
-                            curBlock->collectOnMainThreadOnly.clear(i);
-                            --mainThreadOnlyObjectCount;
-                        }
                         imp->~JSCell();
                     }
                     
@@ -902,11 +840,6 @@
                     if (!curBlock->marked.get(i >> HeapConstants<heapType>::bitmapShift)) {
                         if (heapType != Heap::NumberHeap) {
                             JSCell* imp = reinterpret_cast<JSCell*>(cell);
-                            ASSERT(currentThreadIsMainThread || !curBlock->collectOnMainThreadOnly.get(i));
-                            if (curBlock->collectOnMainThreadOnly.get(i)) {
-                                curBlock->collectOnMainThreadOnly.clear(i);
-                                --mainThreadOnlyObjectCount;
-                            }
                             imp->~JSCell();
                         }
                         --usedCells;
@@ -969,22 +902,16 @@
     primaryHeap.operationInProgress = Collection;
     numberHeap.operationInProgress = Collection;
 
-    bool currentThreadIsMainThread = onMainThread();
-
     // MARK: first mark all referenced objects recursively starting out from the set of root objects
 
     markStackObjectsConservatively();
     markProtectedObjects();
     if (m_markListSet && m_markListSet->size())
         ArgList::markLists(*m_markListSet);
-#if USE(MULTIPLE_THREADS)
-    if (!currentThreadIsMainThread)
-        markMainThreadOnlyObjects();
-#endif
 
     size_t originalLiveObjects = primaryHeap.numLiveObjects + numberHeap.numLiveObjects;
-    size_t numLiveObjects = sweep<PrimaryHeap>(currentThreadIsMainThread);
-    numLiveObjects += sweep<NumberHeap>(currentThreadIsMainThread);
+    size_t numLiveObjects = sweep<PrimaryHeap>();
+    numLiveObjects += sweep<NumberHeap>();
   
     primaryHeap.operationInProgress = NoOperation;
     numberHeap.operationInProgress = NoOperation;
@@ -1000,12 +927,12 @@
 size_t Heap::globalObjectCount()
 {
     size_t count = 0;
-    if (JSGlobalObject::head()) {
-        JSGlobalObject* o = JSGlobalObject::head();
+    if (JSGlobalObject* head = JSGlobalData::threadInstance().head) {
+        JSGlobalObject* o = head;
         do {
             ++count;
             o = o->next();
-        } while (o != JSGlobalObject::head());
+        } while (o != head);
     }
     return count;
 }
@@ -1013,13 +940,13 @@
 size_t Heap::protectedGlobalObjectCount()
 {
     size_t count = 0;
-    if (JSGlobalObject::head()) {
-        JSGlobalObject* o = JSGlobalObject::head();
+    if (JSGlobalObject* head = JSGlobalData::threadInstance().head) {
+        JSGlobalObject* o = head;
         do {
             if (protectedValues.contains(o))
                 ++count;
             o = o->next();
-        } while (o != JSGlobalObject::head());
+        } while (o != head);
     }
     return count;
 }