From eb1f33e3b0faa6391b8a8730b22b61785b87a086 Mon Sep 17 00:00:00 2001 From: Ben Turner Date: Sun, 8 Feb 2009 16:36:55 -0800 Subject: [PATCH] Bug 477319 - "Some objects left locked in tracer code". r=brendan, a=blocking1.9.1+. --- js/src/jslock.cpp | 30 +++++++++++++++++------------- js/src/jsscope.cpp | 9 --------- js/src/jstracer.cpp | 5 ++++- js/src/jsutil.cpp | 16 +++++++++++++--- js/src/jsutil.h | 8 ++++++-- 5 files changed, 40 insertions(+), 28 deletions(-) diff --git a/js/src/jslock.cpp b/js/src/jslock.cpp index 867d0bdecd0..0297a626581 100644 --- a/js/src/jslock.cpp +++ b/js/src/jslock.cpp @@ -303,7 +303,7 @@ js_FinishLock(JSThinLock *tl) #include #include "jsdhash.h" -static FILE *logfp; +static FILE *logfp = NULL; static JSDHashTable logtbl; typedef struct logentry { @@ -314,7 +314,7 @@ typedef struct logentry { } logentry; static void -logit(JSScope *scope, char op, const char *file, int line) +logit(JSTitle *title, char op, const char *file, int line) { logentry *entry; @@ -324,35 +324,35 @@ logit(JSScope *scope, char op, const char *file, int line) return; setvbuf(logfp, NULL, _IONBF, 0); } - fprintf(logfp, "%p %c %s %d\n", scope, op, file, line); + fprintf(logfp, "%p %d %c %s %d\n", title, title->u.count, op, file, line); if (!logtbl.entryStore && !JS_DHashTableInit(&logtbl, JS_DHashGetStubOps(), NULL, sizeof(logentry), 100)) { return; } - entry = (logentry *) JS_DHashTableOperate(&logtbl, scope, JS_DHASH_ADD); + entry = (logentry *) JS_DHashTableOperate(&logtbl, title, JS_DHASH_ADD); if (!entry) return; - entry->stub.key = scope; + entry->stub.key = title; entry->op = op; entry->file = file; entry->line = line; } void -js_unlog_scope(JSScope *scope) +js_unlog_title(JSTitle *title) { if (!logtbl.entryStore) return; - (void) JS_DHashTableOperate(&logtbl, scope, JS_DHASH_REMOVE); + (void) JS_DHashTableOperate(&logtbl, title, JS_DHASH_REMOVE); } -# define LOGIT(scope,op) logit(scope, op, __FILE__, __LINE__) +# define LOGIT(title,op) logit(title, op, __FILE__, __LINE__) #else -# define LOGIT(scope,op) /* nothing */ +# define LOGIT(title, op) /* nothing */ #endif /* DEBUG_SCOPE_COUNT */ @@ -665,7 +665,7 @@ js_GetSlotThreadSafe(JSContext *cx, JSObject *obj, uint32 slot) if (!NativeCompareAndSwap(&tl->owner, me, 0)) { /* Assert that scope locks never revert to flyweight. */ JS_ASSERT(title->ownercx != cx); - LOGIT(scope, '1'); + LOGIT(title, '1'); title->u.count = 1; js_UnlockObj(cx, obj); } @@ -755,7 +755,7 @@ js_SetSlotThreadSafe(JSContext *cx, JSObject *obj, uint32 slot, jsval v) if (!NativeCompareAndSwap(&tl->owner, me, 0)) { /* Assert that scope locks never revert to flyweight. */ JS_ASSERT(title->ownercx != cx); - LOGIT(scope, '1'); + LOGIT(title, '1'); title->u.count = 1; js_UnlockObj(cx, obj); } @@ -1211,7 +1211,7 @@ js_UnlockTitle(JSContext *cx, JSTitle *title) JS_ASSERT(0); /* unbalanced unlock */ return; } - LOGIT(scope, '-'); + LOGIT(title, '-'); if (--title->u.count == 0) ThinUnlock(&title->lock, me); } @@ -1279,7 +1279,7 @@ js_TransferTitle(JSContext *cx, JSTitle *oldtitle, JSTitle *newtitle) /* * Reset oldtitle's lock state so that it is completely unlocked. */ - LOGIT(oldscope, '0'); + LOGIT(oldtitle, '0'); oldtitle->u.count = 0; ThinUnlock(&oldtitle->lock, CX_THINLOCK_ID(cx)); } @@ -1350,6 +1350,10 @@ js_InitTitle(JSContext *cx, JSTitle *title) void js_FinishTitle(JSContext *cx, JSTitle *title) { +#ifdef DEBUG_SCOPE_COUNT + js_unlog_title(title); +#endif + #ifdef JS_THREADSAFE /* Title must be single-threaded at this point, so set ownercx. */ JS_ASSERT(title->u.count == 0); diff --git a/js/src/jsscope.cpp b/js/src/jsscope.cpp index c6a13450f74..941733062f3 100644 --- a/js/src/jsscope.cpp +++ b/js/src/jsscope.cpp @@ -174,11 +174,6 @@ js_NewScope(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops, JSClass *clasp, return scope; } -#ifdef DEBUG_SCOPE_COUNT -extern void -js_unlog_scope(JSScope *scope); -#endif - #if defined DEBUG || defined JS_DUMP_PROPTREE_STATS # include "jsprf.h" # define LIVE_SCOPE_METER(cx,expr) JS_LOCK_RUNTIME_VOID(cx->runtime,expr) @@ -189,10 +184,6 @@ js_unlog_scope(JSScope *scope); void js_DestroyScope(JSContext *cx, JSScope *scope) { -#ifdef DEBUG_SCOPE_COUNT - js_unlog_scope(scope); -#endif - #ifdef JS_THREADSAFE js_FinishTitle(cx, &scope->title); #endif diff --git a/js/src/jstracer.cpp b/js/src/jstracer.cpp index 324bb6287ef..289915efb41 100644 --- a/js/src/jstracer.cpp +++ b/js/src/jstracer.cpp @@ -5530,7 +5530,10 @@ TraceRecorder::test_property_cache(JSObject* obj, LIns* obj_ins, JSObject*& obj2 JSAtom* atom; JSPropCacheEntry* entry; PROPERTY_CACHE_TEST(cx, pc, aobj, obj2, entry, atom); - if (atom) { + if (!atom) { + // Null atom means that obj2 is locked and must now be unlocked. + JS_UNLOCK_OBJ(cx, obj2); + } else { // Miss: pre-fill the cache for the interpreter, as well as for our needs. // FIXME: 452357 - correctly propagate exceptions into the interpreter from // js_FindPropertyHelper, js_LookupPropertyWithFlags, and elsewhere. diff --git a/js/src/jsutil.cpp b/js/src/jsutil.cpp index 5d7eb88d6ff..4b0a0aa6861 100644 --- a/js/src/jsutil.cpp +++ b/js/src/jsutil.cpp @@ -210,7 +210,7 @@ JS_DumpHistogram(JSBasicStats *bs, FILE *fp) #endif /* JS_BASIC_STATS */ -#if defined DEBUG_notme && defined XP_UNIX +#if defined(DEBUG_notme) && defined(XP_UNIX) #define __USE_GNU 1 #include @@ -314,7 +314,7 @@ CallTree(void **bp) return site; } -JSCallsite * +JS_FRIEND_API(JSCallsite *) JS_Backtrace(int skip) { void **bp, **bpdown; @@ -342,4 +342,14 @@ JS_Backtrace(int skip) return CallTree(bp); } -#endif /* DEBUG_notme && XP_UNIX */ +JS_FRIEND_API(void) +JS_DumpBacktrace(JSCallsite *trace) +{ + while (trace) { + fprintf(stdout, "%s [%s +0x%X]\n", trace->name, trace->library, + trace->offset); + trace = trace->parent; + } +} + +#endif /* defined(DEBUG_notme) && defined(XP_UNIX) */ diff --git a/js/src/jsutil.h b/js/src/jsutil.h index a6c329c8a04..7d072bf125c 100644 --- a/js/src/jsutil.h +++ b/js/src/jsutil.h @@ -144,7 +144,7 @@ JS_DumpHistogram(JSBasicStats *bs, FILE *fp); #endif /* JS_BASIC_STATS */ -#ifdef XP_UNIX +#if defined(DEBUG_notme) && defined(XP_UNIX) typedef struct JSCallsite JSCallsite; @@ -159,7 +159,11 @@ struct JSCallsite { void *handy; }; -extern JSCallsite *JS_Backtrace(int skip); +extern JS_FRIEND_API(JSCallsite *) +JS_Backtrace(int skip); + +extern JS_FRIEND_API(void) +JS_DumpBacktrace(JSCallsite *trace); #endif