Make the JS collector work with multiple threads
authoroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 30 Nov 2007 03:02:08 +0000 (03:02 +0000)
committeroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 30 Nov 2007 03:02:08 +0000 (03:02 +0000)
Reviewed by Maciej and Darin.

Under heavy contention it was possible the GC to suspend other
threads inside the pthread spinlock, which could lead to the GC
thread blocking on the pthread spinlock itself.

We now determine and store each thread's stack base when it is
registered, thus removing the need for any calls to pthread_get_stackaddr_np
that needed the pthread spinlock.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@28223 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JavaScriptCore/ChangeLog
JavaScriptCore/kjs/collector.cpp

index d8b9cbd697cd8c23d8f7809de716c6e4c8921074..d432b29fe21fea1a52e11ced23dc4b8695c6c8d6 100644 (file)
@@ -1,3 +1,22 @@
+2007-11-29  Oliver Hunt  <oliver@apple.com>
+
+        Reviewed by Maciej and Darin.
+
+        Make the JS collector work with multiple threads 
+
+        Under heavy contention it was possible the GC to suspend other
+        threads inside the pthread spinlock, which could lead to the GC
+        thread blocking on the pthread spinlock itself.
+
+        We now determine and store each thread's stack base when it is
+        registered, thus removing the need for any calls to pthread_get_stackaddr_np
+        that needed the pthread spinlock.
+
+        * kjs/collector.cpp:
+        (KJS::Collector::Thread::Thread):
+        (KJS::Collector::registerThread):
+        (KJS::Collector::markOtherThreadConservatively):
+
 2007-11-29  Adam Roben  <aroben@apple.com>
 
         Windows build fix
index 7adfb8256a3aecf6ee1313c29ad2c806bf7d2934..4f4408079ac93870cd9a83dcbbaad7e8c7d61c4f 100644 (file)
@@ -408,10 +408,12 @@ static inline PlatformThread getCurrentPlatformThread()
 
 class Collector::Thread {
 public:
-  Thread(pthread_t pthread, const PlatformThread& platThread) : posixThread(pthread), platformThread(platThread) {}
+  Thread(pthread_t pthread, const PlatformThread& platThread, void* base) 
+  : posixThread(pthread), platformThread(platThread), stackBase(base) {}
   Thread* next;
   pthread_t posixThread;
   PlatformThread platformThread;
+  void* stackBase;
 };
 
 pthread_key_t registeredThreadKey;
@@ -464,7 +466,7 @@ void Collector::registerThread()
           CollectorHeapIntrospector::init(&primaryHeap, &numberHeap);
 #endif
 
-    Collector::Thread *thread = new Collector::Thread(pthread_self(), getCurrentPlatformThread());
+    Collector::Thread *thread = new Collector::Thread(pthread_self(), getCurrentPlatformThread(), currentThreadStackBase());
 
     thread->next = registeredThreads;
     registeredThreads = thread;
@@ -675,24 +677,6 @@ static inline void* otherThreadStackPointer(const PlatformThreadRegisters& regs)
 #endif
 }
 
-static inline void* otherThreadStackBase(const PlatformThreadRegisters& regs, Collector::Thread* thread)
-{
-#if PLATFORM(DARWIN)
-  (void)regs;
-  return pthread_get_stackaddr_np(thread->posixThread);
-// end PLATFORM(DARWIN);
-#elif PLATFORM(X86) && PLATFORM(WIN_OS)
-  LDT_ENTRY desc;
-  NT_TIB* tib;
-  GetThreadSelectorEntry(thread->platformThread.handle, regs.SegFs, &desc);
-  tib = (NT_TIB*)(uintptr_t)(desc.BaseLow | desc.HighWord.Bytes.BaseMid << 16 | desc.HighWord.Bytes.BaseHi << 24);
-  ASSERT(tib == tib->Self);
-  return tib->StackBase;
-#else
-#error Need a way to get the stack pointer for another thread on this platform
-#endif
-}
-
 void Collector::markOtherThreadConservatively(Thread* thread)
 {
   suspendThread(thread->platformThread);
@@ -704,8 +688,7 @@ void Collector::markOtherThreadConservatively(Thread* thread)
   markStackObjectsConservatively((void*)&regs, (void*)((char*)&regs + regSize));
  
   void* stackPointer = otherThreadStackPointer(regs);
-  void* stackBase = otherThreadStackBase(regs, thread);
-  markStackObjectsConservatively(stackPointer, stackBase);
+  markStackObjectsConservatively(stackPointer, thread->stackBase);
 
   resumeThread(thread->platformThread);
 }