[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677

mjs mjs at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 06:11:58 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit a59eaef81ea9942e717b8e105a463880425d9ac4
Author: mjs <mjs at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri May 10 16:41:01 2002 +0000

    	Reviewed by: Ken Kocienda and Darin Adler
    
    	Fixed the following bug:
    
    	Radar 2890573 - JavaScriptCore needs to be thread-safe
    
    	Actually this is only a weak form of thread-safety - you can safely
    	use different interpreters from different threads at the same
    	time. If you try to use a single interpreter object from multiple
    	threads, you need to provide your own locking.
    
    	* kjs/collector.h, kjs/collector.cpp:
    	(Collector::lock, Collector::unlock): Trivial implementation of a
    	recursive mutex.
    	(Collector::allocate): Lock around the body of this function.
    	(Collector::collect): Likewise.
    	(Collector::finalCheck): Likewise.
    	(Collector::numInterpreters): Likewise.
    	(Collector::numGCNotAllowedObjects): Likewise.
    	(Collector::numReferencedObjects): Likewise.
    	* kjs/internal.cpp:
    	(Parser::parse): use a mutex to lock around the whole parse, since
    	it uses a bunch of global state.
    	(InterpreterImp::InterpreterImp): Grab the Collector lock here,
    	both the mutually exclude calls to the body of this function, and
    	to protect the s_hook static member which the collector pokes at.
    	(InterpreterImp::clear): Likewise.
    	* kjs/ustring.cpp:
    	(statBufferKeyCleanup, statBufferKeyInit, UString::ascii): Convert
    	use of static variable
    	* kjs/value.cpp:
    	(ValueImp::ValueImp, ValueImp::mark, ValueImp::marked,
    	ValueImp::setGcAllowed): Grab the GC lock around any flag changes.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@1126 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 5790e52..336b1af 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,39 @@
+2002-05-10  Maciej Stachowiak  <mjs at apple.com>
+
+	Reviewed by: Ken Kocienda and Darin Adler
+
+	Fixed the following bug:
+
+	Radar 2890573 - JavaScriptCore needs to be thread-safe
+
+	Actually this is only a weak form of thread-safety - you can safely
+	use different interpreters from different threads at the same
+	time. If you try to use a single interpreter object from multiple
+	threads, you need to provide your own locking.
+
+	* kjs/collector.h, kjs/collector.cpp:
+	(Collector::lock, Collector::unlock): Trivial implementation of a
+	recursive mutex.
+	(Collector::allocate): Lock around the body of this function.
+	(Collector::collect): Likewise.
+	(Collector::finalCheck): Likewise.
+	(Collector::numInterpreters): Likewise.
+	(Collector::numGCNotAllowedObjects): Likewise.
+	(Collector::numReferencedObjects): Likewise.
+	* kjs/internal.cpp:
+	(Parser::parse): use a mutex to lock around the whole parse, since
+	it uses a bunch of global state.
+	(InterpreterImp::InterpreterImp): Grab the Collector lock here,
+	both the mutually exclude calls to the body of this function, and
+	to protect the s_hook static member which the collector pokes at.
+	(InterpreterImp::clear): Likewise.
+	* kjs/ustring.cpp:
+	(statBufferKeyCleanup, statBufferKeyInit, UString::ascii): Convert
+	use of static variable
+	* kjs/value.cpp:
+	(ValueImp::ValueImp, ValueImp::mark, ValueImp::marked,
+	ValueImp::setGcAllowed): Grab the GC lock around any flag changes.
+
 === Alexander-3 ===
 
 2002-05-08  Darin Adler  <darin at apple.com>
diff --git a/JavaScriptCore/ChangeLog-2002-12-03 b/JavaScriptCore/ChangeLog-2002-12-03
index 5790e52..336b1af 100644
--- a/JavaScriptCore/ChangeLog-2002-12-03
+++ b/JavaScriptCore/ChangeLog-2002-12-03
@@ -1,3 +1,39 @@
+2002-05-10  Maciej Stachowiak  <mjs at apple.com>
+
+	Reviewed by: Ken Kocienda and Darin Adler
+
+	Fixed the following bug:
+
+	Radar 2890573 - JavaScriptCore needs to be thread-safe
+
+	Actually this is only a weak form of thread-safety - you can safely
+	use different interpreters from different threads at the same
+	time. If you try to use a single interpreter object from multiple
+	threads, you need to provide your own locking.
+
+	* kjs/collector.h, kjs/collector.cpp:
+	(Collector::lock, Collector::unlock): Trivial implementation of a
+	recursive mutex.
+	(Collector::allocate): Lock around the body of this function.
+	(Collector::collect): Likewise.
+	(Collector::finalCheck): Likewise.
+	(Collector::numInterpreters): Likewise.
+	(Collector::numGCNotAllowedObjects): Likewise.
+	(Collector::numReferencedObjects): Likewise.
+	* kjs/internal.cpp:
+	(Parser::parse): use a mutex to lock around the whole parse, since
+	it uses a bunch of global state.
+	(InterpreterImp::InterpreterImp): Grab the Collector lock here,
+	both the mutually exclude calls to the body of this function, and
+	to protect the s_hook static member which the collector pokes at.
+	(InterpreterImp::clear): Likewise.
+	* kjs/ustring.cpp:
+	(statBufferKeyCleanup, statBufferKeyInit, UString::ascii): Convert
+	use of static variable
+	* kjs/value.cpp:
+	(ValueImp::ValueImp, ValueImp::mark, ValueImp::marked,
+	ValueImp::setGcAllowed): Grab the GC lock around any flag changes.
+
 === Alexander-3 ===
 
 2002-05-08  Darin Adler  <darin at apple.com>
diff --git a/JavaScriptCore/ChangeLog-2003-10-25 b/JavaScriptCore/ChangeLog-2003-10-25
index 5790e52..336b1af 100644
--- a/JavaScriptCore/ChangeLog-2003-10-25
+++ b/JavaScriptCore/ChangeLog-2003-10-25
@@ -1,3 +1,39 @@
+2002-05-10  Maciej Stachowiak  <mjs at apple.com>
+
+	Reviewed by: Ken Kocienda and Darin Adler
+
+	Fixed the following bug:
+
+	Radar 2890573 - JavaScriptCore needs to be thread-safe
+
+	Actually this is only a weak form of thread-safety - you can safely
+	use different interpreters from different threads at the same
+	time. If you try to use a single interpreter object from multiple
+	threads, you need to provide your own locking.
+
+	* kjs/collector.h, kjs/collector.cpp:
+	(Collector::lock, Collector::unlock): Trivial implementation of a
+	recursive mutex.
+	(Collector::allocate): Lock around the body of this function.
+	(Collector::collect): Likewise.
+	(Collector::finalCheck): Likewise.
+	(Collector::numInterpreters): Likewise.
+	(Collector::numGCNotAllowedObjects): Likewise.
+	(Collector::numReferencedObjects): Likewise.
+	* kjs/internal.cpp:
+	(Parser::parse): use a mutex to lock around the whole parse, since
+	it uses a bunch of global state.
+	(InterpreterImp::InterpreterImp): Grab the Collector lock here,
+	both the mutually exclude calls to the body of this function, and
+	to protect the s_hook static member which the collector pokes at.
+	(InterpreterImp::clear): Likewise.
+	* kjs/ustring.cpp:
+	(statBufferKeyCleanup, statBufferKeyInit, UString::ascii): Convert
+	use of static variable
+	* kjs/value.cpp:
+	(ValueImp::ValueImp, ValueImp::mark, ValueImp::marked,
+	ValueImp::setGcAllowed): Grab the GC lock around any flag changes.
+
 === Alexander-3 ===
 
 2002-05-08  Darin Adler  <darin at apple.com>
diff --git a/JavaScriptCore/kjs/collector.cpp b/JavaScriptCore/kjs/collector.cpp
index e46f26e..e561fd6 100644
--- a/JavaScriptCore/kjs/collector.cpp
+++ b/JavaScriptCore/kjs/collector.cpp
@@ -29,6 +29,9 @@
 #ifdef KJS_DEBUG_MEM
 #include <typeinfo>
 #endif
+#ifdef APPLE_CHANGES
+#include <pthread.h>
+#endif
 
 namespace KJS {
 
@@ -46,6 +49,7 @@ namespace KJS {
 
 using namespace KJS;
 
+
 CollectorBlock::CollectorBlock(int s)
   : size(s),
     filled(0),
@@ -62,6 +66,14 @@ CollectorBlock::~CollectorBlock()
   mem = 0L;
 }
 
+#ifdef APPLE_CHANGES
+// FIXME: fix these once static initializers for pthread_cond_t and
+// pthread_mutex_t are fixed not to warn.
+static pthread_mutex_t collectorLock = {_PTHREAD_MUTEX_SIG_init, {}};
+static pthread_cond_t collectorCondition = {_PTHREAD_COND_SIG_init, {}};
+static unsigned collectorLockCount = 0;
+static pthread_t collectorLockThread;
+#endif
 CollectorBlock* Collector::root = 0L;
 CollectorBlock* Collector::currentBlock = 0L;
 unsigned long Collector::filled = 0;
@@ -81,6 +93,10 @@ void* Collector::allocate(size_t s)
   if (s == 0)
     return 0L;
 
+#ifdef APPLE_CHANGES
+  lock();
+#endif
+
   // Try and deal with memory requirements in a scalable way. Simple scripts
   // should only require small amounts of memory, but for complex scripts we don't
   // want to end up running the garbage collector hundreds of times a second.
@@ -147,6 +163,10 @@ void* Collector::allocate(size_t s)
     fprintf(stderr,"Out of memory");
   }
 
+#ifdef APPLE_CHANGES
+  unlock();
+#endif
+
   return m;
 }
 
@@ -155,6 +175,9 @@ void* Collector::allocate(size_t s)
  */
 bool Collector::collect()
 {
+#ifdef APPLE_CHANGES
+  lock();
+#endif
 #ifdef KJS_DEBUG_MEM
   fprintf(stderr,"Collector::collect()\n");
 #endif
@@ -252,12 +275,18 @@ bool Collector::collect()
   if (s_count++ % 50 == 2)
     finalCheck();
 #endif
+#ifdef APPLE_CHANGES
+  unlock();
+#endif
   return deleted;
 }
 
 #ifdef KJS_DEBUG_MEM
 void Collector::finalCheck()
 {
+#ifdef APPLE_CHANGES
+  lock();
+#endif
   CollectorBlock *block = root;
   while (block) {
     ValueImp **r = (ValueImp**)block->mem;
@@ -273,12 +302,16 @@ void Collector::finalCheck()
     }
     block = block->next;
   }
+#ifdef APPLE_CHANGES
+  unlock();
+#endif
 }
 #endif
 
 #ifdef APPLE_CHANGES
 int Collector::numInterpreters()
 {
+  lock();
   int count = 0;
   if (InterpreterImp::s_hook) {
     InterpreterImp *scr = InterpreterImp::s_hook;
@@ -287,11 +320,13 @@ int Collector::numInterpreters()
       scr = scr->next;
     } while (scr != InterpreterImp::s_hook);
   }
+  unlock();
   return count;
 }
 
 int Collector::numGCNotAllowedObjects()
 {
+  lock();
   int count = 0;
   CollectorBlock *block = root;
   while (block) {
@@ -306,11 +341,13 @@ int Collector::numGCNotAllowedObjects()
     }
     block = block->next;
   }
+  unlock();
   return count;
 }
 
 int Collector::numReferencedObjects()
 {
+  lock();
   int count = 0;
   CollectorBlock *block = root;
   while (block) {
@@ -325,6 +362,30 @@ int Collector::numReferencedObjects()
     }
     block = block->next;
   }
+  unlock();
   return count;
 }
+
+void Collector::lock()
+{
+  pthread_mutex_lock(&collectorLock);
+  while (collectorLockCount > 0 && 
+	 !pthread_equal(pthread_self(), collectorLockThread)) {
+    pthread_cond_wait(&collectorCondition, &collectorLock);
+  }
+  collectorLockThread = pthread_self();
+  collectorLockCount++;
+  pthread_mutex_unlock(&collectorLock);
+}
+
+void Collector::unlock()
+{
+  pthread_mutex_lock(&collectorLock);
+  collectorLockCount--;
+  if (collectorLockCount == 0) {
+    pthread_cond_signal(&collectorCondition);
+  }
+  pthread_mutex_unlock(&collectorLock);
+}
+
 #endif
diff --git a/JavaScriptCore/kjs/collector.h b/JavaScriptCore/kjs/collector.h
index d0649e0..61b08b2 100644
--- a/JavaScriptCore/kjs/collector.h
+++ b/JavaScriptCore/kjs/collector.h
@@ -92,6 +92,8 @@ namespace KJS {
     static int numInterpreters();
     static int numGCNotAllowedObjects();
     static int numReferencedObjects();
+    static void lock();
+    static void unlock();
 #endif
   private:
     static CollectorBlock* root;
diff --git a/JavaScriptCore/kjs/internal.cpp b/JavaScriptCore/kjs/internal.cpp
index 2aec51f..217a617 100644
--- a/JavaScriptCore/kjs/internal.cpp
+++ b/JavaScriptCore/kjs/internal.cpp
@@ -688,10 +688,16 @@ void ContextImp::popScope()
 
 ProgramNode *Parser::progNode = 0;
 int Parser::sid = 0;
+#ifdef APPLE_CHANGES
+static pthread_mutex_t parserLock = {_PTHREAD_MUTEX_SIG_init, {}};
+#endif
 
 ProgramNode *Parser::parse(const UChar *code, unsigned int length, int *sourceId,
 			   int *errLine, UString *errMsg)
 {
+#ifdef APPLE_CHANGES
+  pthread_mutex_lock(&parserLock);
+#endif
   if (errLine)
     *errLine = -1;
   if (errMsg)
@@ -720,9 +726,15 @@ ProgramNode *Parser::parse(const UChar *code, unsigned int length, int *sourceId
     fprintf(stderr, "KJS: JavaScript parse error at line %d.\n", eline);
 #endif
     delete prog;
+#ifdef APPLE_CHANGES
+    pthread_mutex_unlock(&parserLock);
+#endif
     return 0;
   }
 
+#ifdef APPLE_CHANGES
+  pthread_mutex_unlock(&parserLock);
+#endif
   return prog;
 }
 
@@ -764,6 +776,9 @@ InterpreterImp::InterpreterImp(Interpreter *interp, const Object &glob)
 {
   // add this interpreter to the global chain
   // as a root set for garbage collection
+#ifdef APPLE_CHANGES
+  Collector::lock();
+#endif
   if (s_hook) {
     prev = s_hook;
     next = s_hook->next;
@@ -774,6 +789,9 @@ InterpreterImp::InterpreterImp(Interpreter *interp, const Object &glob)
     s_hook = next = prev = this;
     globalInit();
   }
+#ifdef APPLE_CHANGES
+  Collector::unlock();
+#endif
 
   m_interpreter = interp;
   global = glob;
@@ -926,6 +944,9 @@ void InterpreterImp::clear()
 {
   //fprintf(stderr,"InterpreterImp::clear\n");
   // remove from global chain (see init())
+#ifdef APPLE_CHANGES
+  Collector::lock();
+#endif
   next->prev = prev;
   prev->next = next;
   s_hook = next;
@@ -935,6 +956,9 @@ void InterpreterImp::clear()
     s_hook = 0L;
     globalClear();
   }
+#ifdef APPLE_CHANGES
+  Collector::unlock();
+#endif
 }
 
 void InterpreterImp::mark()
diff --git a/JavaScriptCore/kjs/ustring.cpp b/JavaScriptCore/kjs/ustring.cpp
index 9c5ca51..fe17987 100644
--- a/JavaScriptCore/kjs/ustring.cpp
+++ b/JavaScriptCore/kjs/ustring.cpp
@@ -121,7 +121,13 @@ bool KJS::operator==(const KJS::CString& c1, const KJS::CString& c2)
 UChar UChar::null;
 UString::Rep UString::Rep::null = { 0, 0, 1 };
 UString UString::null;
+#ifdef APPLE_CHANGES
+// FIXME: fix this once static initializers for pthread_once_t
+pthread_once_t statBufferKeyOnce = {_PTHREAD_ONCE_SIG_init, {}};
+pthread_key_t statBufferKey;
+#else
 static char *statBuffer = 0L;
+#endif
 
 UChar::UChar(const UCharReference &c)
     : uc( c.unicode() )
@@ -277,8 +283,25 @@ CString UString::cstring() const
   return CString(ascii());
 }
 
+#ifdef APPLE_CHANGES
+static void statBufferKeyCleanup(void *statBuffer)
+{
+  if (statBuffer != NULL)
+    delete [] (char *)statBuffer;
+}
+
+static void statBufferKeyInit(void)
+{
+  pthread_key_create(&statBufferKey, statBufferKeyCleanup);
+}
+#endif
+
 char *UString::ascii() const
 {
+#ifdef APPLE_CHANGES
+  pthread_once(&statBufferKeyOnce, statBufferKeyInit);
+  char *statBuffer = (char *)pthread_getspecific(statBufferKey);
+#endif
   if (statBuffer)
     delete [] statBuffer;
 
@@ -287,6 +310,9 @@ char *UString::ascii() const
     statBuffer[i] = data()[i].low();
   statBuffer[size()] = '\0';
 
+#ifdef APPLE_CHANGES
+  pthread_setspecific(statBufferKey, statBuffer);
+#endif
   return statBuffer;
 }
 
diff --git a/JavaScriptCore/kjs/value.cpp b/JavaScriptCore/kjs/value.cpp
index ec48212..caf4d3a 100644
--- a/JavaScriptCore/kjs/value.cpp
+++ b/JavaScriptCore/kjs/value.cpp
@@ -41,6 +41,17 @@ using namespace KJS;
 
 // ------------------------------ ValueImp -------------------------------------
 
+#if APPLE_CHANGES
+ValueImp::ValueImp() :
+  refcount(0)
+{
+  // Tell the garbage collector that this memory block corresponds to a real object now
+  Collector::lock();
+  _flags = VI_CREATED;
+  //fprintf(stderr,"ValueImp::ValueImp %p\n",(void*)this);
+  Collector::unlock();
+}
+#else
 ValueImp::ValueImp() :
   refcount(0),
   // Tell the garbage collector that this memory block corresponds to a real object now
@@ -48,6 +59,7 @@ ValueImp::ValueImp() :
 {
   //fprintf(stderr,"ValueImp::ValueImp %p\n",(void*)this);
 }
+#endif
 
 ValueImp::~ValueImp()
 {
@@ -67,8 +79,14 @@ bool ValueImp::marked() const
 
 void ValueImp::setGcAllowed()
 {
+#ifdef APPLE_CHANGES
+  Collector::lock();
+#endif
   //fprintf(stderr,"ValueImp::setGcAllowed %p\n",(void*)this);
   _flags |= VI_GCALLOWED;
+#ifdef APPLE_CHANGES
+  Collector::unlock();
+#endif
 }
 
 void* ValueImp::operator new(size_t s)
diff --git a/JavaScriptCore/kjs/value.h b/JavaScriptCore/kjs/value.h
index b6d76c0..25b76c0 100644
--- a/JavaScriptCore/kjs/value.h
+++ b/JavaScriptCore/kjs/value.h
@@ -94,6 +94,30 @@ namespace KJS {
     ValueImp();
     virtual ~ValueImp();
 
+#ifdef APPLE_CHANGES
+    // The collecter lock is not locked around the ref() and unref()
+    // methods for the following reasons:
+    //
+    // - The only cases where chaging the refcount could possibly
+    // affect the collector's behavior is incrementing from 0 to 1,
+    // and decrementing from 1 to 0.
+    //
+    // - In the 0 to 1 case, the GC allowed flag will always be off
+    // beforehand, and set right afterwards. And setting it grabs the
+    // collector lock. So if this happens in the middle of GC, the
+    // collector will see either a refcount 0 GC not allowed object,
+    // or a refcount 1 GC not allowed object, and these cases are
+    // treated exactly the same.
+    //
+    // - In the 1 to 0 case, the only possible bad effect is that the
+    // object will live for one GC cycle longer than it should have
+    // to, which is really not so bad.
+    //
+    // - In theory on some platforms increment or decrement could make
+    // other threads see intermediate values that are different from
+    // both the start and end value. If that turns out to really be
+    // the case we will have to reconsider this scheme.
+#endif
     inline ValueImp* ref() { refcount++; return this; }
     inline bool deref() { return (!--refcount); }
     unsigned int refcount;

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list