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 d8b9cbd..d432b29 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 7adfb82..4f44080 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);
 }