[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