diff --git a/js/src/jsatom.cpp b/js/src/jsatom.cpp index 1016eaeee56c..8437c3fbd711 100644 --- a/js/src/jsatom.cpp +++ b/js/src/jsatom.cpp @@ -578,19 +578,19 @@ js_AtomizeDouble(JSContext *cx, jsdouble d) state = &cx->runtime->atomState; table = &state->doubleAtoms; - JS_LOCK(&state->lock, cx); + JS_LOCK(cx, &state->lock); entry = TO_ATOM_ENTRY(JS_DHashTableOperate(table, &d, JS_DHASH_ADD)); if (!entry) goto failed_hash_add; if (entry->keyAndFlags == 0) { gen = ++table->generation; - JS_UNLOCK(&state->lock, cx); + JS_UNLOCK(cx, &state->lock); key = js_NewWeaklyRootedDouble(cx, d); if (!key) return NULL; - JS_LOCK(&state->lock, cx); + JS_LOCK(cx, &state->lock); if (table->generation == gen) { JS_ASSERT(entry->keyAndFlags == 0); } else { @@ -608,12 +608,12 @@ js_AtomizeDouble(JSContext *cx, jsdouble d) finish: v = DOUBLE_TO_JSVAL((jsdouble *)ATOM_ENTRY_KEY(entry)); cx->weakRoots.lastAtom = v; - JS_UNLOCK(&state->lock,cx); + JS_UNLOCK(cx, &state->lock); return (JSAtom *)v; failed_hash_add: - JS_UNLOCK(&state->lock,cx); + JS_UNLOCK(cx, &state->lock); JS_ReportOutOfMemory(cx); return NULL; } @@ -634,7 +634,7 @@ js_AtomizeString(JSContext *cx, JSString *str, uintN flags) state = &cx->runtime->atomState; table = &state->stringAtoms; - JS_LOCK(&state->lock, cx); + JS_LOCK(cx, &state->lock); entry = TO_ATOM_ENTRY(JS_DHashTableOperate(table, str, JS_DHASH_ADD)); if (!entry) goto failed_hash_add; @@ -653,7 +653,7 @@ js_AtomizeString(JSContext *cx, JSString *str, uintN flags) key = str; } else { gen = table->generation; - JS_UNLOCK(&state->lock, cx); + JS_UNLOCK(cx, &state->lock); if (flags & ATOM_TMPSTR) { if (flags & ATOM_NOCOPY) { @@ -677,7 +677,7 @@ js_AtomizeString(JSContext *cx, JSString *str, uintN flags) key = str; } - JS_LOCK(&state->lock, cx); + JS_LOCK(cx, &state->lock); if (table->generation == gen) { JS_ASSERT(entry->keyAndFlags == 0); } else { @@ -701,11 +701,11 @@ js_AtomizeString(JSContext *cx, JSString *str, uintN flags) JS_ASSERT(JSSTRING_IS_ATOMIZED(key)); v = STRING_TO_JSVAL(key); cx->weakRoots.lastAtom = v; - JS_UNLOCK(&state->lock, cx); + JS_UNLOCK(cx, &state->lock); return (JSAtom *)v; failed_hash_add: - JS_UNLOCK(&state->lock,cx); + JS_UNLOCK(cx, &state->lock); JS_ReportOutOfMemory(cx); return NULL; } @@ -766,12 +766,12 @@ js_GetExistingStringAtom(JSContext *cx, const jschar *chars, size_t length) JSFLATSTR_INIT(&str, (jschar *)chars, length); state = &cx->runtime->atomState; - JS_LOCK(&state->lock, cx); + JS_LOCK(cx, &state->lock); hdr = JS_DHashTableOperate(&state->stringAtoms, &str, JS_DHASH_LOOKUP); str2 = JS_DHASH_ENTRY_IS_BUSY(hdr) ? (JSString *)ATOM_ENTRY_KEY(TO_ATOM_ENTRY(hdr)) : NULL; - JS_UNLOCK(&state->lock, cx); + JS_UNLOCK(cx, &state->lock); return str2 ? (JSAtom *)STRING_TO_JSVAL(str2) : NULL; } diff --git a/js/src/jslock.cpp b/js/src/jslock.cpp index 9eba3efc29b6..8ade762094fe 100644 --- a/js/src/jslock.cpp +++ b/js/src/jslock.cpp @@ -61,7 +61,7 @@ #ifndef NSPR_LOCK -/* Implement NativeCompareAndSwap. */ +/* Implement NativeCompareAndSwap. */ #if defined(_WIN32) && defined(_M_IX86) #pragma warning( disable : 4035 ) @@ -189,13 +189,29 @@ NativeCompareAndSwap(jsword *w, jsword ov, jsword nv) #endif /* arch-tests */ +struct JSFatLock { + int susp; + PRLock *slock; + PRCondVar *svar; + JSFatLock *next; + JSFatLock **prevp; +}; + +typedef struct JSFatLockTable { + JSFatLock *free; + JSFatLock *taken; +} JSFatLockTable; + +#define GLOBAL_LOCK_INDEX(id) (((uint32)(jsuword)(id)>>2) & global_locks_mask) + +static void +js_Dequeue(JSThinLock *); + static PRLock **global_locks; static uint32 global_lock_count = 1; static uint32 global_locks_log2 = 0; static uint32 global_locks_mask = 0; -#define GLOBAL_LOCK_INDEX(id) (((uint32)(jsuword)(id)>>2) & global_locks_mask) - static void js_LockGlobal(void *id) { @@ -236,10 +252,6 @@ js_FinishLock(JSThinLock *tl) #endif } -#ifndef NSPR_LOCK -static void js_Dequeue(JSThinLock *); -#endif - #ifdef DEBUG_SCOPE_COUNT #include @@ -888,7 +900,23 @@ js_CleanupLocks() #endif /* !NSPR_LOCK */ } -#ifndef NSPR_LOCK +#ifdef NSPR_LOCK + +static JS_INLINE void +ThinLock(JSThinLock *tl, jsword me) +{ + JS_ACQUIRE_LOCK((JSLock *) tl->fat); + tl->owner = me; +} + +static JS_INLINE void +ThinUnlock(JSThinLock *tl, jsword /*me*/) +{ + tl->owner = 0; + JS_RELEASE_LOCK((JSLock *) tl->fat); +} + +#else /* * Fast locking and unlocking is implemented by delaying the allocation of a @@ -1005,8 +1033,8 @@ js_Dequeue(JSThinLock *tl) js_ResumeThread(tl); } -JS_INLINE void -js_Lock(JSThinLock *tl, jsword me) +static JS_INLINE void +ThinLock(JSThinLock *tl, jsword me) { JS_ASSERT(CURRENT_THREAD_IS_ME(me)); if (NativeCompareAndSwap(&tl->owner, 0, me)) @@ -1019,8 +1047,8 @@ js_Lock(JSThinLock *tl, jsword me) #endif } -JS_INLINE void -js_Unlock(JSThinLock *tl, jsword me) +static JS_INLINE void +ThinUnlock(JSThinLock *tl, jsword me) { JS_ASSERT(CURRENT_THREAD_IS_ME(me)); @@ -1042,6 +1070,18 @@ js_Unlock(JSThinLock *tl, jsword me) #endif /* !NSPR_LOCK */ +void +js_Lock(JSContext *cx, JSThinLock *tl) +{ + ThinLock(tl, CX_THINLOCK_ID(cx)); +} + +void +js_Unlock(JSContext *cx, JSThinLock *tl) +{ + ThinUnlock(tl, CX_THINLOCK_ID(cx)); +} + void js_LockRuntime(JSRuntime *rt) { @@ -1077,8 +1117,7 @@ js_LockTitle(JSContext *cx, JSTitle *title) LOGIT(scope, '+'); title->u.count++; } else { - JSThinLock *tl = &title->lock; - JS_LOCK0(tl, me); + ThinLock(&title->lock, me); JS_ASSERT(title->u.count == 0); LOGIT(scope, '1'); title->u.count = 1; @@ -1125,10 +1164,8 @@ js_UnlockTitle(JSContext *cx, JSTitle *title) return; } LOGIT(scope, '-'); - if (--title->u.count == 0) { - JSThinLock *tl = &title->lock; - JS_UNLOCK0(tl, me); - } + if (--title->u.count == 0) + ThinUnlock(&title->lock, me); } /* @@ -1138,9 +1175,6 @@ js_UnlockTitle(JSContext *cx, JSTitle *title) void js_TransferTitle(JSContext *cx, JSTitle *oldtitle, JSTitle *newtitle) { - jsword me; - JSThinLock *tl; - JS_ASSERT(JS_IS_TITLE_LOCKED(cx, newtitle)); /* @@ -1199,9 +1233,7 @@ js_TransferTitle(JSContext *cx, JSTitle *oldtitle, JSTitle *newtitle) */ LOGIT(oldscope, '0'); oldtitle->u.count = 0; - tl = &oldtitle->lock; - me = CX_THINLOCK_ID(cx); - JS_UNLOCK0(tl, me); + ThinUnlock(&oldtitle->lock, CX_THINLOCK_ID(cx)); } void diff --git a/js/src/jslock.h b/js/src/jslock.h index efb3272870a2..ff32143e5d4a 100644 --- a/js/src/jslock.h +++ b/js/src/jslock.h @@ -66,20 +66,18 @@ JS_BEGIN_EXTERN_C # define JS_HAS_NATIVE_COMPARE_AND_SWAP 0 #endif +#if defined(JS_USE_ONLY_NSPR_LOCKS) || !JS_HAS_NATIVE_COMPARE_AND_SWAP +# define NSPR_LOCK 1 +#else +# undef NSPR_LOCK +#endif + #define Thin_GetWait(W) ((jsword)(W) & 0x1) #define Thin_SetWait(W) ((jsword)(W) | 0x1) #define Thin_RemoveWait(W) ((jsword)(W) & ~0x1) typedef struct JSFatLock JSFatLock; -struct JSFatLock { - int susp; - PRLock *slock; - PRCondVar *svar; - JSFatLock *next; - JSFatLock **prevp; -}; - typedef struct JSThinLock { jsword owner; JSFatLock *fat; @@ -90,11 +88,6 @@ typedef struct JSThinLock { typedef PRLock JSLock; -typedef struct JSFatLockTable { - JSFatLock *free; - JSFatLock *taken; -} JSFatLockTable; - typedef struct JSTitle JSTitle; struct JSTitle { @@ -133,8 +126,6 @@ struct JSTitle { #define JS_DESTROY_LOCK(l) PR_DestroyLock(l) #define JS_ACQUIRE_LOCK(l) PR_Lock(l) #define JS_RELEASE_LOCK(l) PR_Unlock(l) -#define JS_LOCK0(P,M) js_Lock(P,M) -#define JS_UNLOCK0(P,M) js_Unlock(P,M) #define JS_NEW_CONDVAR(l) PR_NewCondVar(l) #define JS_DESTROY_CONDVAR(cv) PR_DestroyCondVar(cv) @@ -153,6 +144,9 @@ struct JSTitle { #endif +#define JS_LOCK(cx, tl) js_Lock(cx, tl) +#define JS_UNLOCK(cx, tl) js_Unlock(cx, tl) + #define JS_LOCK_RUNTIME(rt) js_LockRuntime(rt) #define JS_UNLOCK_RUNTIME(rt) js_UnlockRuntime(rt) @@ -184,6 +178,9 @@ struct JSTitle { #define JS_TRANSFER_SCOPE_LOCK(cx, scope, newscope) \ js_TransferTitle(cx, &scope->title, &newscope->title) + +extern void js_Lock(JSContext *cx, JSThinLock *tl); +extern void js_Unlock(JSContext *cx, JSThinLock *tl); extern void js_LockRuntime(JSRuntime *rt); extern void js_UnlockRuntime(JSRuntime *rt); extern void js_LockObj(JSContext *cx, JSObject *obj); @@ -236,24 +233,6 @@ extern void js_SetScopeInfo(JSScope *scope, const char *file, int line); JS_LOCK_RUNTIME_VOID(_rt, e); \ JS_END_MACRO -#if defined(JS_USE_ONLY_NSPR_LOCKS) || !JS_HAS_NATIVE_COMPARE_AND_SWAP - -#define NSPR_LOCK 1 - -#undef JS_LOCK0 -#undef JS_UNLOCK0 -#define JS_LOCK0(P,M) (JS_ACQUIRE_LOCK(((JSLock*)(P)->fat)), (P)->owner = (M)) -#define JS_UNLOCK0(P,M) ((P)->owner = 0, JS_RELEASE_LOCK(((JSLock*)(P)->fat))) - -#else - -#undef NSPR_LOCK - -extern void js_Lock(JSThinLock *tl, jsword me); -extern void js_Unlock(JSThinLock *tl, jsword me); - -#endif - #else /* !JS_THREADSAFE */ #define JS_ATOMIC_INCREMENT(p) (++*(p)) @@ -265,8 +244,8 @@ extern void js_Unlock(JSThinLock *tl, jsword me); #define JS_DESTROY_LOCK(l) ((void)0) #define JS_ACQUIRE_LOCK(l) ((void)0) #define JS_RELEASE_LOCK(l) ((void)0) -#define JS_LOCK0(P,M) ((void)0) -#define JS_UNLOCK0(P,M) ((void)0) +#define JS_LOCK(cx, tl) ((void)0) +#define JS_UNLOCK(cx, tl) ((void)0) #define JS_NEW_CONDVAR(l) NULL #define JS_DESTROY_CONDVAR(cv) ((void)0) @@ -306,9 +285,6 @@ extern void js_Unlock(JSThinLock *tl, jsword me); JS_NO_TIMEOUT) #define JS_NOTIFY_REQUEST_DONE(rt) JS_NOTIFY_CONDVAR((rt)->requestDone) -#define JS_LOCK(P,CX) JS_LOCK0(P, CX_THINLOCK_ID(CX)) -#define JS_UNLOCK(P,CX) JS_UNLOCK0(P, CX_THINLOCK_ID(CX)) - #ifndef SET_OBJ_INFO #define SET_OBJ_INFO(obj,f,l) ((void)0) #endif