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/InitializeThreading.cpp b/JavaScriptCore/kjs/InitializeThreading.cpp
index 177f0f6..ec0b2ce 100644
--- a/JavaScriptCore/kjs/InitializeThreading.cpp
+++ b/JavaScriptCore/kjs/InitializeThreading.cpp
@@ -48,9 +48,6 @@
     WTF::initializeThreading();
 #if USE(MULTIPLE_THREADS)
     s_dtoaP5Mutex = new Mutex;
-#if !PLATFORM(DARWIN) // Darwin has pthread_main_np(), and doesn't need registerAsMainThread() called.
-    Heap::registerAsMainThread();
-#endif
     JSGlobalData::threadInstance();
     UString::null();
     initDateMath();
diff --git a/JavaScriptCore/kjs/JSGlobalData.cpp b/JavaScriptCore/kjs/JSGlobalData.cpp
index f3f951c..0b61d3d 100644
--- a/JavaScriptCore/kjs/JSGlobalData.cpp
+++ b/JavaScriptCore/kjs/JSGlobalData.cpp
@@ -89,6 +89,10 @@
 JSGlobalData::~JSGlobalData()
 {
 #if USE(MULTIPLE_THREADS)
+    delete heap;
+
+    delete machine;
+
     delete[] arrayTable->table;
     delete[] dateTable->table;
     delete[] mathTable->table;
@@ -109,6 +113,9 @@
 
     delete propertyNames;
     deleteIdentifierTable(identifierTable);
+
+    delete newParserObjects;
+    delete parserObjectExtraRefCounts;
 #endif
 }
 
@@ -125,15 +132,12 @@
 
 JSGlobalData& JSGlobalData::sharedInstance()
 {
-    return threadInstance();
-/*
 #if USE(MULTIPLE_THREADS)
     AtomicallyInitializedStatic(JSGlobalData, sharedInstance);
 #else
     static JSGlobalData sharedInstance;
 #endif
     return sharedInstance;
-*/
 }
 
 }
diff --git a/JavaScriptCore/kjs/JSGlobalData.h b/JavaScriptCore/kjs/JSGlobalData.h
index 8f27123..6ced870 100644
--- a/JavaScriptCore/kjs/JSGlobalData.h
+++ b/JavaScriptCore/kjs/JSGlobalData.h
@@ -72,7 +72,6 @@
         CommonIdentifiers* propertyNames;
         const ArgList emptyList; // Lists are supposed to be allocated on the stack to have their elements properly marked, which is not the case here - but this list has nothing to mark.
 
-        // Tracked object sets are transient, only needed when parsing.
         HashSet<ParserRefCounted*>* newParserObjects;
         HashCountedSet<ParserRefCounted*>* parserObjectExtraRefCounts;
 
diff --git a/JavaScriptCore/kjs/JSGlobalObject.cpp b/JavaScriptCore/kjs/JSGlobalObject.cpp
index 3077ca4..1971bb6 100644
--- a/JavaScriptCore/kjs/JSGlobalObject.cpp
+++ b/JavaScriptCore/kjs/JSGlobalObject.cpp
@@ -91,6 +91,8 @@
 
 JSGlobalObject::~JSGlobalObject()
 {
+    ASSERT(JSLock::currentThreadIsHoldingLock());
+
     if (d()->debugger)
         d()->debugger->detach(this);
 
@@ -113,6 +115,8 @@
 {
     ASSERT(JSLock::currentThreadIsHoldingLock());
 
+    d()->globalData = (Heap::heap(this) == JSGlobalData::sharedInstance().heap) ? &JSGlobalData::sharedInstance() : &JSGlobalData::threadInstance();
+
     if (JSGlobalObject*& headObject = head()) {
         d()->prev = headObject;
         d()->next = headObject->d()->next;
@@ -128,8 +132,6 @@
     d()->recursion = 0;
     d()->debugger = 0;
     
-    d()->globalData = (Heap::heap(this) == JSGlobalData::sharedInstance().heap) ? &JSGlobalData::sharedInstance() : &JSGlobalData::threadInstance();
-
     d()->globalExec.set(new ExecState(this, thisValue, d()->globalScopeChain.node()));
 
     d()->pageGroupIdentifier = 0;
diff --git a/JavaScriptCore/kjs/JSGlobalObject.h b/JavaScriptCore/kjs/JSGlobalObject.h
index 7eb83b9..5915cdf 100644
--- a/JavaScriptCore/kjs/JSGlobalObject.h
+++ b/JavaScriptCore/kjs/JSGlobalObject.h
@@ -161,7 +161,7 @@
         virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunc);
 
         // Per-thread linked list of all global objects.
-        static JSGlobalObject*& head() { return JSGlobalData::threadInstance().head; }
+        JSGlobalObject*& head() { return d()->globalData->head; }
         JSGlobalObject* next() { return d()->next; }
 
         // Resets the global object to contain only built-in properties, sets
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;
 }
diff --git a/JavaScriptCore/kjs/collector.h b/JavaScriptCore/kjs/collector.h
index c30800b..bfdb373 100644
--- a/JavaScriptCore/kjs/collector.h
+++ b/JavaScriptCore/kjs/collector.h
@@ -77,8 +77,6 @@
         void protect(JSValue*);
         void unprotect(JSValue*);
 
-        void collectOnMainThreadOnly(JSValue*);
-
         static Heap* heap(const JSValue*); // 0 for immediate values
 
         size_t globalObjectCount();
@@ -86,7 +84,6 @@
         size_t protectedGlobalObjectCount();
         HashCountedSet<const char*>* protectedObjectTypeCounts();
 
-        static void registerAsMainThread();
         static void registerThread(); // Should only be called by clients that can use the same heap from multiple threads.
 
 #if PLATFORM(DARWIN) && USE(MULTIPLE_THREADS)
@@ -102,17 +99,17 @@
 
     private:
         template <Heap::HeapType heapType> void* heapAllocate(size_t);
-        template <Heap::HeapType heapType> size_t sweep(bool);
+        template <Heap::HeapType heapType> size_t sweep();
         static const CollectorBlock* cellBlock(const JSCell*);
         static CollectorBlock* cellBlock(JSCell*);
         static size_t cellOffset(const JSCell*);
 
         Heap();
+        ~Heap();
         friend class JSGlobalData;
 
         void recordExtraCost(size_t);
         void markProtectedObjects();
-        void markMainThreadOnlyObjects();
         void markCurrentThreadConservatively();
         void markCurrentThreadConservativelyInternal();
         void markOtherThreadConservatively(Thread*);
@@ -120,7 +117,6 @@
 
         typedef HashCountedSet<JSCell*> ProtectCountSet;
 
-        size_t mainThreadOnlyObjectCount;
         CollectorHeap primaryHeap;
         CollectorHeap numberHeap;
         ProtectCountSet protectedValues;
@@ -183,7 +179,6 @@
         uint32_t usedCells;
         CollectorCell* freeList;
         CollectorBitmap marked;
-        CollectorBitmap collectOnMainThreadOnly;
         Heap* heap;
     };
 
@@ -193,7 +188,6 @@
         uint32_t usedCells;
         SmallCollectorCell* freeList;
         CollectorBitmap marked;
-        CollectorBitmap collectOnMainThreadOnly;
         Heap* heap;
     };