Changeset 34947 in webkit for trunk/JavaScriptCore/kjs


Ignore:
Timestamp:
Jul 2, 2008, 12:00:53 AM (17 years ago)
Author:
[email protected]
Message:

Reviewed by Darin.

Disable JSLock for per-thread contexts.

No change on SunSpider.

  • kjs/JSGlobalData.h:
  • kjs/JSGlobalData.cpp: (KJS::JSGlobalData::JSGlobalData): (KJS::JSGlobalData::sharedInstance): Added isSharedInstance as a better way to tell whether the instance is shared (legacy).
  • kjs/JSLock.cpp: (KJS::createJSLockCount): (KJS::JSLock::lockCount): (KJS::setLockCount): (KJS::JSLock::JSLock): (KJS::JSLock::lock): (KJS::JSLock::unlock): (KJS::JSLock::currentThreadIsHoldingLock): (KJS::JSLock::DropAllLocks::DropAllLocks): (KJS::JSLock::DropAllLocks::~DropAllLocks):
  • kjs/JSLock.h: (KJS::JSLock::JSLock): (KJS::JSLock::~JSLock): Made JSLock and JSLock::DropAllLocks constructors take a parameter to decide whether to actually lock a mutex, or only to increment recursion count. We cannot turn it into no-op if we want to keep existing assertions working. Made recursion count per-thread, now that locks may not lock.
  • API/JSBase.cpp: (JSEvaluateScript): Take JSLock after casting JSContextRef to ExecState* (which doesn't need locking in any case), so that a decision whether to actually lock can be made. (JSCheckScriptSyntax): Ditto. (JSGarbageCollect): Only lock while collecting the shared heap, not the per-thread one.
  • API/JSObjectRef.cpp: (JSClassCreate): Don't lock, as there is no reason to. (JSClassRetain): Ditto. (JSClassRelease): Ditto. (JSPropertyNameArrayRetain): Ditto. (JSPropertyNameArrayRelease): Only lock while deleting the array, as that may touch identifier table. (JSPropertyNameAccumulatorAddName): Adding a string also involves an identifier table lookup, and possibly modification.
  • API/JSStringRef.cpp: (JSStringCreateWithCharacters): (JSStringCreateWithUTF8CString): (JSStringRetain): (JSStringRelease): (JSStringGetUTF8CString): (JSStringIsEqual):
  • API/JSStringRefCF.cpp: (JSStringCreateWithCFString): JSStringRef operations other than releasing do not need locking.
  • VM/Machine.cpp: Don't include unused JSLock.h.
  • kjs/CollectorHeapIntrospector.cpp: (KJS::CollectorHeapIntrospector::statistics): Don't take the lock for real, as heap introspection pauses the process anyway. It seems that the existing code could cause deadlocks.
  • kjs/Shell.cpp: (functionGC): (main): (jscmain): The test tool uses a per-thread context, so no real locking is required.
  • kjs/collector.h: (KJS::Heap::setGCProtectNeedsLocking): Optionally protect m_protectedValues access with a per-heap mutex. This is only needed for WebCore Database code, which violates the "no data migration between threads" by using ProtectedPtr on a background thread. (KJS::Heap::isShared): Keep a shared flag here, as well.
  • kjs/protect.h: (KJS::::ProtectedPtr): (KJS::::~ProtectedPtr): (KJS::::operator): (KJS::operator==): (KJS::operator!=): ProtectedPtr is ony used from WebCore, so it doesn't need to take JSLock. An assertion in Heap::protect/unprotect guards agains possible future unlocked uses of ProtectedPtr in JSC.
  • kjs/collector.cpp: (KJS::Heap::Heap): Initialize m_isShared. (KJS::Heap::~Heap): No need to lock for real during destruction, but must keep assertions in sweep() working. (KJS::destroyRegisteredThread): Registered thread list is only accessed for shared heap, so locking is always needed here. (KJS::Heap::registerThread): Ditto. (KJS::Heap::markStackObjectsConservatively): Use m_isShared instead of comparing to a shared instance for a small speedup. (KJS::Heap::setGCProtectNeedsLocking): Create m_protectedValuesMutex. There is currently no way to undo this - and ideally, Database code will be fixed to lo longer require this quirk. (KJS::Heap::protect): Take m_protectedValuesMutex (if it exists) while accessing m_protectedValues. (KJS::Heap::unprotect): Ditto. (KJS::Heap::markProtectedObjects): Ditto. (KJS::Heap::protectedGlobalObjectCount): Ditto. (KJS::Heap::protectedObjectCount): Ditto. (KJS::Heap::protectedObjectTypeCounts): Ditto.
  • kjs/ustring.cpp:
  • kjs/ustring.h: Don't include JSLock.h, which is no longer used here. As a result, an explicit include had to be added to many files in JavaScriptGlue, WebCore and WebKit.
  • kjs/JSGlobalObject.cpp: (KJS::JSGlobalObject::init):
  • API/JSCallbackConstructor.cpp: (KJS::constructJSCallback):
  • API/JSCallbackFunction.cpp: (KJS::JSCallbackFunction::call):
  • API/JSCallbackObjectFunctions.h: (KJS::::init): (KJS::::getOwnPropertySlot): (KJS::::put): (KJS::::deleteProperty): (KJS::::construct): (KJS::::hasInstance): (KJS::::call): (KJS::::getPropertyNames): (KJS::::toNumber): (KJS::::toString): (KJS::::staticValueGetter): (KJS::::callbackGetter):
  • API/JSContextRef.cpp: (JSGlobalContextCreate): (JSGlobalContextRetain): (JSGlobalContextRelease):
  • API/JSValueRef.cpp: (JSValueIsEqual): (JSValueIsStrictEqual): (JSValueIsInstanceOfConstructor): (JSValueMakeNumber): (JSValueMakeString): (JSValueToNumber): (JSValueToStringCopy): (JSValueToObject): (JSValueProtect): (JSValueUnprotect):
  • JavaScriptCore.exp:
  • kjs/PropertyNameArray.h: (KJS::PropertyNameArray::globalData):
  • kjs/interpreter.cpp: (KJS::Interpreter::checkSyntax): (KJS::Interpreter::evaluate): Pass a parameter to JSLock/JSLock::DropAllLocks to decide whether the lock needs to be taken.
Location:
trunk/JavaScriptCore/kjs
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/CollectorHeapIntrospector.cpp

    r34824 r34947  
    9696void CollectorHeapIntrospector::statistics(malloc_zone_t* zone, malloc_statistics_t* stats)
    9797{
    98     JSLock lock;
     98    JSLock lock(false);
    9999    CollectorHeapIntrospector* introspector = reinterpret_cast<CollectorHeapIntrospector*>(zone);
    100100    CollectorHeap* primaryHeap = introspector->m_primaryHeap;
  • trunk/JavaScriptCore/kjs/JSGlobalData.cpp

    r34907 r34947  
    5757
    5858
    59 JSGlobalData::JSGlobalData()
     59JSGlobalData::JSGlobalData(bool isShared)
    6060    : machine(new Machine)
    61     , heap(new Heap)
     61    , heap(new Heap(isShared))
    6262#if USE(MULTIPLE_THREADS)
    6363    , arrayTable(new HashTable(KJS::arrayTable))
     
    8484    , parser(new Parser)
    8585    , head(0)
     86    , isSharedInstance(isShared)
    8687{
    8788}
     
    133134{
    134135#if USE(MULTIPLE_THREADS)
    135     AtomicallyInitializedStatic(JSGlobalData, sharedInstance);
    136 #else
    137     static JSGlobalData sharedInstance;
     136    MutexLocker locker(*atomicallyInitializedStaticMutex);
    138137#endif
    139     return sharedInstance;
     138    static JSGlobalData* sharedInstance;
     139    if (!sharedInstance)
     140        sharedInstance = new JSGlobalData(true);
     141    return *sharedInstance;
    140142}
    141143
  • trunk/JavaScriptCore/kjs/JSGlobalData.h

    r34838 r34947  
    8282        JSGlobalObject* head;
    8383
     84        bool isSharedInstance;
     85
    8486    private:
    8587        friend class WTF::ThreadSpecific<JSGlobalData>;
    8688
    87         JSGlobalData();
     89        JSGlobalData(bool isShared = false);
    8890        ~JSGlobalData();
    8991    };
  • trunk/JavaScriptCore/kjs/JSGlobalObject.cpp

    r34946 r34947  
    102102    ASSERT(JSLock::currentThreadIsHoldingLock());
    103103
    104     d()->globalData = (Heap::heap(this) == JSGlobalData::sharedInstance().heap) ? &JSGlobalData::sharedInstance() : &JSGlobalData::threadInstance();
     104    d()->globalData = Heap::heap(this)->isShared() ? &JSGlobalData::sharedInstance() : &JSGlobalData::threadInstance();
    105105
    106106    if (JSGlobalObject*& headObject = head()) {
  • trunk/JavaScriptCore/kjs/JSLock.cpp

    r34659 r34947  
    2525
    2626#include "collector.h"
     27#include "ExecState.h"
     28
    2729#if USE(MULTIPLE_THREADS)
    2830#include <pthread.h>
     
    3638static pthread_mutex_t JSMutex = PTHREAD_MUTEX_INITIALIZER;
    3739
    38 // Thread-specific key that tells whether a thread holds the JSMutex.
    39 pthread_key_t didLockJSMutex;
     40// Thread-specific key that tells whether a thread holds the JSMutex, and how many times it was taken recursively.
     41pthread_key_t JSLockCount;
     42
     43static void createJSLockCount()
     44{
     45    pthread_key_create(&JSLockCount, 0);
     46}
     47
     48pthread_once_t createJSLockCountOnce = PTHREAD_ONCE_INIT;
    4049
    4150// Lock nesting count.
    42 static int JSLockCount;
     51int JSLock::lockCount()
     52{
     53    pthread_once(&createJSLockCountOnce, createJSLockCount);
    4354
    44 static void createDidLockJSMutex()
     55    return reinterpret_cast<int>(pthread_getspecific(JSLockCount));
     56}
     57
     58static void setLockCount(int count)
    4559{
    46     pthread_key_create(&didLockJSMutex, 0);
     60    pthread_setspecific(JSLockCount, reinterpret_cast<void*>(count));
    4761}
    48 pthread_once_t createDidLockJSMutexOnce = PTHREAD_ONCE_INIT;
    4962
    50 void JSLock::lock()
     63JSLock::JSLock(ExecState* exec)
     64    : m_lockingForReal(exec->globalData().isSharedInstance)
    5165{
    52     pthread_once(&createDidLockJSMutexOnce, createDidLockJSMutex);
     66    lock(m_lockingForReal);
     67    if (m_lockingForReal)
     68        registerThread();
     69}
    5370
    54     if (!pthread_getspecific(didLockJSMutex)) {
     71void JSLock::lock(bool lockForReal)
     72{
     73#ifdef NDEBUG
     74    // For per-thread contexts, locking is a debug-only feature.
     75    if (!lockForReal)
     76        return;
     77#endif
     78
     79    pthread_once(&createJSLockCountOnce, createJSLockCount);
     80
     81    int currentLockCount = lockCount();
     82    if (!currentLockCount && lockForReal) {
    5583        int result;
    5684        result = pthread_mutex_lock(&JSMutex);
    5785        ASSERT(!result);
    58         pthread_setspecific(didLockJSMutex, &didLockJSMutex);
    5986    }
    60     ++JSLockCount;
     87    setLockCount(currentLockCount + 1);
    6188}
    6289
    63 void JSLock::unlock()
     90void JSLock::unlock(bool lockForReal)
    6491{
    65     ASSERT(JSLockCount);
    66     ASSERT(!!pthread_getspecific(didLockJSMutex));
     92    ASSERT(lockCount());
    6793
    68     --JSLockCount;
    69     if (!JSLockCount) {
    70         pthread_setspecific(didLockJSMutex, 0);
     94#ifdef NDEBUG
     95    // For per-thread contexts, locking is a debug-only feature.
     96    if (!lockForReal)
     97        return;
     98#endif
     99
     100    int newLockCount = lockCount() - 1;
     101    setLockCount(newLockCount);
     102    if (!newLockCount && lockForReal) {
    71103        int result;
    72104        result = pthread_mutex_unlock(&JSMutex);
     
    75107}
    76108
     109void JSLock::lock(ExecState* exec)
     110{
     111    lock(exec->globalData().isSharedInstance);
     112}
     113
     114void JSLock::unlock(ExecState* exec)
     115{
     116    unlock(exec->globalData().isSharedInstance);
     117}
     118
    77119bool JSLock::currentThreadIsHoldingLock()
    78120{
    79     pthread_once(&createDidLockJSMutexOnce, createDidLockJSMutex);
    80     return !!pthread_getspecific(didLockJSMutex);
     121    pthread_once(&createJSLockCountOnce, createJSLockCount);
     122    return !!pthread_getspecific(JSLockCount);
    81123}
    82124
     
    86128}
    87129
    88 JSLock::DropAllLocks::DropAllLocks()
    89     : m_lockCount(0)
     130JSLock::DropAllLocks::DropAllLocks(ExecState* exec)
     131    : m_lockingForReal(exec->globalData().isSharedInstance)
    90132{
    91     pthread_once(&createDidLockJSMutexOnce, createDidLockJSMutex);
     133    pthread_once(&createJSLockCountOnce, createJSLockCount);
    92134
    93     m_lockCount = !!pthread_getspecific(didLockJSMutex) ? JSLock::lockCount() : 0;
     135    m_lockCount = JSLock::lockCount();
    94136    for (int i = 0; i < m_lockCount; i++)
    95         JSLock::unlock();
     137        JSLock::unlock(m_lockingForReal);
     138}
     139
     140JSLock::DropAllLocks::DropAllLocks(bool lockingForReal)
     141    : m_lockingForReal(lockingForReal)
     142{
     143    pthread_once(&createJSLockCountOnce, createJSLockCount);
     144
     145    // It is necessary to drop even "unreal" locks, because having a non-zero lock count
     146    // will prevent a real lock from being taken.
     147
     148    m_lockCount = JSLock::lockCount();
     149    for (int i = 0; i < m_lockCount; i++)
     150        JSLock::unlock(m_lockingForReal);
    96151}
    97152
     
    99154{
    100155    for (int i = 0; i < m_lockCount; i++)
    101         JSLock::lock();
    102     m_lockCount = 0;
     156        JSLock::lock(m_lockingForReal);
    103157}
    104158
     
    107161// If threading support is off, set the lock count to a constant value of 1 so assertions
    108162// that the lock is held don't fail
    109 const int JSLockCount = 1;
     163int JSLock::lockCount()
     164{
     165    return 1;
     166}
    110167
    111168bool JSLock::currentThreadIsHoldingLock()
     
    136193#endif // USE(MULTIPLE_THREADS)
    137194
    138 int JSLock::lockCount()
    139 {
    140     return JSLockCount;
    141195}
    142 
    143 }
  • trunk/JavaScriptCore/kjs/JSLock.h

    r33038 r34947  
    4747    // thread acquired it to begin with.
    4848
     49    // For per-thread contexts, JSLock doesn't do any locking, but we
     50    // still need to perform all the counting in order to keep debug
     51    // assertions working, so that clients that use a shared context don't break.
     52
     53    class ExecState;
     54
    4955    class JSLock : Noncopyable {
    5056    public:
    51         JSLock()
     57        JSLock(ExecState* exec);
     58
     59        JSLock(bool lockingForReal)
     60            : m_lockingForReal(lockingForReal)
    5261        {
    53             lock();
    54             registerThread();
     62#ifdef NDEBUG
     63            // For per-thread contexts, locking is a debug-only feature.
     64            if (!lockingForReal)
     65                return;
     66#endif
     67            lock(lockingForReal);
     68            if (lockingForReal)
     69                registerThread();
    5570        }
    5671
    57         ~JSLock() 
     72        ~JSLock()
    5873        {
    59             unlock();
     74#ifdef NDEBUG
     75            // For per-thread contexts, locking is a debug-only feature.
     76            if (!m_lockingForReal)
     77                return;
     78#endif
     79            unlock(m_lockingForReal);
    6080        }
    6181       
    62         static void lock();
    63         static void unlock();
     82        static void lock(bool);
     83        static void unlock(bool);
     84        static void lock(ExecState*);
     85        static void unlock(ExecState*);
     86
    6487        static int lockCount();
    6588        static bool currentThreadIsHoldingLock();
     
    6790        static void registerThread();
    6891
     92        bool m_lockingForReal;
     93
    6994        class DropAllLocks : Noncopyable {
    7095        public:
    71             DropAllLocks();
     96            DropAllLocks(ExecState* exec);
     97            DropAllLocks(bool);
    7298            ~DropAllLocks();
    7399           
    74100        private:
    75101            int m_lockCount;
     102            bool m_lockingForReal;
    76103        };
    77104    };
  • trunk/JavaScriptCore/kjs/PropertyNameArray.h

    r34611 r34947  
    3838        PropertyNameArray(ExecState* exec) : m_globalData(&exec->globalData()) {}
    3939
     40        JSGlobalData* globalData() { return m_globalData; }
     41
    4042        void add(const Identifier& identifier) { add(identifier.ustring().rep()); }
    4143        void add(UString::Rep*);
  • trunk/JavaScriptCore/kjs/Shell.cpp

    r34854 r34947  
    207207JSValue* functionGC(ExecState* exec, JSObject*, JSValue*, const ArgList&)
    208208{
    209     JSLock lock;
     209    JSLock lock(false);
    210210    exec->heap()->collect();
    211211    return jsUndefined();
     
    302302        res = jscmain(argc, argv);
    303303#ifndef NDEBUG
    304         JSLock::lock();
     304        JSLock::lock(false);
    305305        JSGlobalData::threadInstance().heap->collect();
    306         JSLock::unlock();
     306        JSLock::unlock(false);
    307307#endif
    308308    EXCEPT(res = 3)
     
    448448int jscmain(int argc, char** argv)
    449449{
    450     initializeThreading();
    451 
    452     JSLock lock;
     450    KJS::initializeThreading();
     451
     452    JSLock lock(false);
    453453
    454454    Options options;
  • trunk/JavaScriptCore/kjs/collector.cpp

    r34907 r34947  
    2424#include "ExecState.h"
    2525#include "JSGlobalObject.h"
     26#include "JSLock.h"
    2627#include "JSString.h"
    2728#include "JSValue.h"
     
    9192static void freeHeap(CollectorHeap*);
    9293
    93 Heap::Heap()
     94Heap::Heap(bool isShared)
    9495    : m_markListSet(0)
     96    , m_isShared(isShared)
    9597{
    9698    memset(&primaryHeap, 0, sizeof(CollectorHeap));
     
    100102Heap::~Heap()
    101103{
    102     JSLock lock;
     104    JSLock lock(false);
    103105
    104106    delete m_markListSet;
     
    439441    // Can't use JSLock convenience object here because we don't want to re-register
    440442    // an exiting thread.
    441     JSLock::lock();
     443    // JSLock is only used for code simplicity here, as we only need to protect registeredThreads
     444    // list manipulation, not JS data structures.
     445    JSLock::lock(true);
    442446
    443447    if (registeredThreads == thread) {
     
    456460    }
    457461
    458     JSLock::unlock();
     462    JSLock::unlock(true);
    459463
    460464    delete thread;
     
    468472void Heap::registerThread()
    469473{
     474    // Since registerThread() is only called when using a shared heap, these locks will be real.
    470475    ASSERT(JSLock::lockCount() > 0);
    471476    ASSERT(JSLock::currentThreadIsHoldingLock());
     
    729734#if USE(MULTIPLE_THREADS)
    730735
    731     if (this == JSGlobalData::sharedInstance().heap) {
     736    if (m_isShared) {
    732737
    733738#ifndef NDEBUG
     
    737742        fastMallocForbid();
    738743#endif
     744        // It is safe to access the registeredThreads list, because we earlier asserted that locks are being held,
     745        // and since this is a shared heap, they are real locks.
    739746        for (Thread* thread = registeredThreads; thread != NULL; thread = thread->next) {
    740747            if (!pthread_equal(thread->posixThread, pthread_self()))
     
    748755}
    749756
     757void Heap::setGCProtectNeedsLocking()
     758{
     759    // Most clients do not need to call this, with the notable exception of WebCore.
     760    // Clients that use shared heap have JSLock protection, while others are not supposed
     761    // to migrate JS objects between threads. WebCore violates this contract in Database code,
     762    // which calls gcUnprotect from a secondary thread.
     763    if (!m_protectedValuesMutex)
     764        m_protectedValuesMutex.set(new Mutex);
     765}
     766
    750767void Heap::protect(JSValue* k)
    751768{
    752769    ASSERT(k);
    753     ASSERT(JSLock::lockCount() > 0);
    754     ASSERT(JSLock::currentThreadIsHoldingLock());
     770    ASSERT(JSLock::currentThreadIsHoldingLock() || !m_isShared);
    755771
    756772    if (JSImmediate::isImmediate(k))
    757773        return;
    758774
    759     protectedValues.add(k->asCell());
     775    if (m_protectedValuesMutex)
     776        m_protectedValuesMutex->lock();
     777
     778    m_protectedValues.add(k->asCell());
     779
     780    if (m_protectedValuesMutex)
     781        m_protectedValuesMutex->unlock();
    760782}
    761783
     
    763785{
    764786    ASSERT(k);
    765     ASSERT(JSLock::lockCount() > 0);
    766     ASSERT(JSLock::currentThreadIsHoldingLock());
     787    ASSERT(JSLock::currentThreadIsHoldingLock() || !m_isShared);
    767788
    768789    if (JSImmediate::isImmediate(k))
    769790        return;
    770791
    771     protectedValues.remove(k->asCell());
     792    if (m_protectedValuesMutex)
     793        m_protectedValuesMutex->lock();
     794
     795    m_protectedValues.remove(k->asCell());
     796
     797    if (m_protectedValuesMutex)
     798        m_protectedValuesMutex->unlock();
    772799}
    773800
     
    781808void Heap::markProtectedObjects()
    782809{
    783     ProtectCountSet::iterator end = protectedValues.end();
    784     for (ProtectCountSet::iterator it = protectedValues.begin(); it != end; ++it) {
     810    if (m_protectedValuesMutex)
     811        m_protectedValuesMutex->lock();
     812
     813    ProtectCountSet::iterator end = m_protectedValues.end();
     814    for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it) {
    785815        JSCell* val = it->first;
    786816        if (!val->marked())
    787817            val->mark();
    788818    }
     819
     820    if (m_protectedValuesMutex)
     821        m_protectedValuesMutex->unlock();
    789822}
    790823
     
    941974size_t Heap::protectedGlobalObjectCount()
    942975{
     976    if (m_protectedValuesMutex)
     977        m_protectedValuesMutex->lock();
     978
    943979    size_t count = 0;
    944980    if (JSGlobalObject* head = JSGlobalData::threadInstance().head) {
    945981        JSGlobalObject* o = head;
    946982        do {
    947             if (protectedValues.contains(o))
     983            if (m_protectedValues.contains(o))
    948984                ++count;
    949985            o = o->next();
    950986        } while (o != head);
    951987    }
     988
     989    if (m_protectedValuesMutex)
     990        m_protectedValuesMutex->unlock();
     991
    952992    return count;
    953993}
     
    955995size_t Heap::protectedObjectCount()
    956996{
    957     return protectedValues.size();
     997    if (m_protectedValuesMutex)
     998        m_protectedValuesMutex->lock();
     999
     1000    size_t result = m_protectedValues.size();
     1001
     1002    if (m_protectedValuesMutex)
     1003        m_protectedValuesMutex->unlock();
     1004
     1005    return result;
    9581006}
    9591007
     
    9951043    HashCountedSet<const char*>* counts = new HashCountedSet<const char*>;
    9961044
    997     ProtectCountSet::iterator end = protectedValues.end();
    998     for (ProtectCountSet::iterator it = protectedValues.begin(); it != end; ++it)
     1045    if (m_protectedValuesMutex)
     1046        m_protectedValuesMutex->lock();
     1047
     1048    ProtectCountSet::iterator end = m_protectedValues.end();
     1049    for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it)
    9991050        counts->add(typeName(it->first));
    10001051
     1052    if (m_protectedValuesMutex)
     1053        m_protectedValuesMutex->unlock();
     1054
    10011055    return counts;
    10021056}
  • trunk/JavaScriptCore/kjs/collector.h

    r34907 r34947  
    2727#include <wtf/HashSet.h>
    2828#include <wtf/Noncopyable.h>
     29#include <wtf/OwnPtr.h>
     30#include <wtf/Threading.h>
    2931
    3032namespace KJS {
     
    7678        size_t size();
    7779
     80        void setGCProtectNeedsLocking();
    7881        void protect(JSValue*);
    7982        void unprotect(JSValue*);
     
    98101
    99102        HashSet<ArgList*>& markListSet() { if (!m_markListSet) m_markListSet = new HashSet<ArgList*>; return *m_markListSet; }
     103
     104        bool isShared() const { return m_isShared; }
    100105
    101106    private:
     
    106111        static size_t cellOffset(const JSCell*);
    107112
    108         friend class Machine;
    109113        friend class JSGlobalData;
    110         Heap();
     114        Heap(bool isShared);
    111115        ~Heap();
    112116
     
    122126        CollectorHeap primaryHeap;
    123127        CollectorHeap numberHeap;
    124         ProtectCountSet protectedValues;
     128
     129        OwnPtr<Mutex> m_protectedValuesMutex; // Only non-null if the client explicitly requested it via setGCPrtotectNeedsLocking().
     130        ProtectCountSet m_protectedValues;
     131
    125132        HashSet<ArgList*>* m_markListSet;
     133
     134        bool m_isShared;
    126135    };
    127136
  • trunk/JavaScriptCore/kjs/interpreter.cpp

    r34842 r34947  
    4646Completion Interpreter::checkSyntax(ExecState* exec, const UString& sourceURL, int startingLineNumber, PassRefPtr<SourceProvider> source)
    4747{
    48     JSLock lock;
     48    JSLock lock(exec);
    4949
    5050    int errLine;
     
    6464Completion Interpreter::evaluate(ExecState* exec, ScopeChain& scopeChain, const UString& sourceURL, int startingLineNumber, PassRefPtr<SourceProvider> source, JSValue* thisValue)
    6565{
    66     JSLock lock;
     66    JSLock lock(exec);
    6767   
    6868    // parse the source code
  • trunk/JavaScriptCore/kjs/protect.h

    r34659 r34947  
    2727#include "JSValue.h"
    2828#include "collector.h"
    29 #include "JSLock.h"
    3029
    3130namespace KJS {
     
    6362        ProtectedPtr() : m_ptr(NULL) { }
    6463        ProtectedPtr(T *ptr);
    65         ProtectedPtr(const ProtectedPtr &);
     64        ProtectedPtr(const ProtectedPtr&);
    6665        ~ProtectedPtr();
    6766
    68         template <class U> ProtectedPtr(const ProtectedPtr<U> &);
     67        template <class U> ProtectedPtr(const ProtectedPtr<U>&);
    6968       
    7069        T *get() const { return m_ptr; }
     
    7473        bool operator!() const { return m_ptr == NULL; }
    7574
    76         ProtectedPtr &operator=(const ProtectedPtr &);
    77         ProtectedPtr &operator=(T *);
     75        ProtectedPtr& operator=(const ProtectedPtr&);
     76        ProtectedPtr& operator=(T*);
    7877       
    7978    private:
     
    8483        : m_ptr(ptr)
    8584    {
    86         if (ptr) {
    87             JSLock lock;
     85        if (ptr)
    8886            gcProtect(ptr);
    89         }
    9087    }
    9188
    92     template <class T> ProtectedPtr<T>::ProtectedPtr(const ProtectedPtr &o)
     89    template <class T> ProtectedPtr<T>::ProtectedPtr(const ProtectedPtr& o)
    9390        : m_ptr(o.get())
    9491    {
    95         if (T *ptr = m_ptr) {
    96             JSLock lock;
     92        if (T *ptr = m_ptr)
    9793            gcProtect(ptr);
    98         }
    9994    }
    10095
    10196    template <class T> ProtectedPtr<T>::~ProtectedPtr()
    10297    {
    103         if (T *ptr = m_ptr) {
    104             JSLock lock;
     98        if (T *ptr = m_ptr)
    10599            gcUnprotect(ptr);
    106         }
    107100    }
    108101
    109     template <class T> template <class U> ProtectedPtr<T>::ProtectedPtr(const ProtectedPtr<U> &o)
     102    template <class T> template <class U> ProtectedPtr<T>::ProtectedPtr(const ProtectedPtr<U>& o)
    110103        : m_ptr(o.get())
    111104    {
    112         if (T *ptr = m_ptr) {
    113             JSLock lock;
     105        if (T *ptr = m_ptr)
    114106            gcProtect(ptr);
    115         }
    116107    }
    117108
    118     template <class T> ProtectedPtr<T> &ProtectedPtr<T>::operator=(const ProtectedPtr<T> &o)
     109    template <class T> ProtectedPtr<T>& ProtectedPtr<T>::operator=(const ProtectedPtr<T>& o)
    119110    {
    120         JSLock lock;
    121111        T *optr = o.m_ptr;
    122112        gcProtectNullTolerant(optr);
     
    126116     }
    127117
    128     template <class T> inline ProtectedPtr<T> &ProtectedPtr<T>::operator=(T *optr)
     118    template <class T> inline ProtectedPtr<T>& ProtectedPtr<T>::operator=(T* optr)
    129119    {
    130         JSLock lock;
    131120        gcProtectNullTolerant(optr);
    132121        gcUnprotectNullTolerant(m_ptr);
     
    135124    }
    136125
    137     template <class T> inline bool operator==(const ProtectedPtr<T> &a, const ProtectedPtr<T> &b) { return a.get() == b.get(); }
    138     template <class T> inline bool operator==(const ProtectedPtr<T> &a, const T *b) { return a.get() == b; }
    139     template <class T> inline bool operator==(const T *a, const ProtectedPtr<T> &b) { return a == b.get(); }
     126    template <class T> inline bool operator==(const ProtectedPtr<T>& a, const ProtectedPtr<T>& b) { return a.get() == b.get(); }
     127    template <class T> inline bool operator==(const ProtectedPtr<T>& a, const T* b) { return a.get() == b; }
     128    template <class T> inline bool operator==(const T* a, const ProtectedPtr<T>& b) { return a == b.get(); }
    140129
    141     template <class T> inline bool operator!=(const ProtectedPtr<T> &a, const ProtectedPtr<T> &b) { return a.get() != b.get(); }
    142     template <class T> inline bool operator!=(const ProtectedPtr<T> &a, const T *b) { return a.get() != b; }
    143     template <class T> inline bool operator!=(const T *a, const ProtectedPtr<T> &b) { return a != b.get(); }
     130    template <class T> inline bool operator!=(const ProtectedPtr<T>& a, const ProtectedPtr<T>& b) { return a.get() != b.get(); }
     131    template <class T> inline bool operator!=(const ProtectedPtr<T>& a, const T* b) { return a.get() != b; }
     132    template <class T> inline bool operator!=(const T* a, const ProtectedPtr<T>& b) { return a != b.get(); }
    144133 
    145134} // namespace
  • trunk/JavaScriptCore/kjs/ustring.cpp

    r34821 r34947  
    2525#include "ustring.h"
    2626
    27 #include "JSLock.h"
    2827#include "collector.h"
    2928#include "dtoa.h"
  • trunk/JavaScriptCore/kjs/ustring.h

    r34821 r34947  
    2424#define _KJS_USTRING_H_
    2525
    26 #include "JSLock.h"
    2726#include "collector.h"
    2827#include <stdint.h>
Note: See TracChangeset for help on using the changeset viewer.