зеркало из https://github.com/mozilla/pjs.git
Bug 477319 - "Some objects left locked in tracer code". r=brendan, a=blocking1.9.1+.
This commit is contained in:
Родитель
fa5489e581
Коммит
eb1f33e3b0
|
@ -303,7 +303,7 @@ js_FinishLock(JSThinLock *tl)
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "jsdhash.h"
|
#include "jsdhash.h"
|
||||||
|
|
||||||
static FILE *logfp;
|
static FILE *logfp = NULL;
|
||||||
static JSDHashTable logtbl;
|
static JSDHashTable logtbl;
|
||||||
|
|
||||||
typedef struct logentry {
|
typedef struct logentry {
|
||||||
|
@ -314,7 +314,7 @@ typedef struct logentry {
|
||||||
} logentry;
|
} logentry;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
logit(JSScope *scope, char op, const char *file, int line)
|
logit(JSTitle *title, char op, const char *file, int line)
|
||||||
{
|
{
|
||||||
logentry *entry;
|
logentry *entry;
|
||||||
|
|
||||||
|
@ -324,35 +324,35 @@ logit(JSScope *scope, char op, const char *file, int line)
|
||||||
return;
|
return;
|
||||||
setvbuf(logfp, NULL, _IONBF, 0);
|
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 &&
|
if (!logtbl.entryStore &&
|
||||||
!JS_DHashTableInit(&logtbl, JS_DHashGetStubOps(), NULL,
|
!JS_DHashTableInit(&logtbl, JS_DHashGetStubOps(), NULL,
|
||||||
sizeof(logentry), 100)) {
|
sizeof(logentry), 100)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
entry = (logentry *) JS_DHashTableOperate(&logtbl, scope, JS_DHASH_ADD);
|
entry = (logentry *) JS_DHashTableOperate(&logtbl, title, JS_DHASH_ADD);
|
||||||
if (!entry)
|
if (!entry)
|
||||||
return;
|
return;
|
||||||
entry->stub.key = scope;
|
entry->stub.key = title;
|
||||||
entry->op = op;
|
entry->op = op;
|
||||||
entry->file = file;
|
entry->file = file;
|
||||||
entry->line = line;
|
entry->line = line;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
js_unlog_scope(JSScope *scope)
|
js_unlog_title(JSTitle *title)
|
||||||
{
|
{
|
||||||
if (!logtbl.entryStore)
|
if (!logtbl.entryStore)
|
||||||
return;
|
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
|
#else
|
||||||
|
|
||||||
# define LOGIT(scope,op) /* nothing */
|
# define LOGIT(title, op) /* nothing */
|
||||||
|
|
||||||
#endif /* DEBUG_SCOPE_COUNT */
|
#endif /* DEBUG_SCOPE_COUNT */
|
||||||
|
|
||||||
|
@ -665,7 +665,7 @@ js_GetSlotThreadSafe(JSContext *cx, JSObject *obj, uint32 slot)
|
||||||
if (!NativeCompareAndSwap(&tl->owner, me, 0)) {
|
if (!NativeCompareAndSwap(&tl->owner, me, 0)) {
|
||||||
/* Assert that scope locks never revert to flyweight. */
|
/* Assert that scope locks never revert to flyweight. */
|
||||||
JS_ASSERT(title->ownercx != cx);
|
JS_ASSERT(title->ownercx != cx);
|
||||||
LOGIT(scope, '1');
|
LOGIT(title, '1');
|
||||||
title->u.count = 1;
|
title->u.count = 1;
|
||||||
js_UnlockObj(cx, obj);
|
js_UnlockObj(cx, obj);
|
||||||
}
|
}
|
||||||
|
@ -755,7 +755,7 @@ js_SetSlotThreadSafe(JSContext *cx, JSObject *obj, uint32 slot, jsval v)
|
||||||
if (!NativeCompareAndSwap(&tl->owner, me, 0)) {
|
if (!NativeCompareAndSwap(&tl->owner, me, 0)) {
|
||||||
/* Assert that scope locks never revert to flyweight. */
|
/* Assert that scope locks never revert to flyweight. */
|
||||||
JS_ASSERT(title->ownercx != cx);
|
JS_ASSERT(title->ownercx != cx);
|
||||||
LOGIT(scope, '1');
|
LOGIT(title, '1');
|
||||||
title->u.count = 1;
|
title->u.count = 1;
|
||||||
js_UnlockObj(cx, obj);
|
js_UnlockObj(cx, obj);
|
||||||
}
|
}
|
||||||
|
@ -1211,7 +1211,7 @@ js_UnlockTitle(JSContext *cx, JSTitle *title)
|
||||||
JS_ASSERT(0); /* unbalanced unlock */
|
JS_ASSERT(0); /* unbalanced unlock */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LOGIT(scope, '-');
|
LOGIT(title, '-');
|
||||||
if (--title->u.count == 0)
|
if (--title->u.count == 0)
|
||||||
ThinUnlock(&title->lock, me);
|
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.
|
* Reset oldtitle's lock state so that it is completely unlocked.
|
||||||
*/
|
*/
|
||||||
LOGIT(oldscope, '0');
|
LOGIT(oldtitle, '0');
|
||||||
oldtitle->u.count = 0;
|
oldtitle->u.count = 0;
|
||||||
ThinUnlock(&oldtitle->lock, CX_THINLOCK_ID(cx));
|
ThinUnlock(&oldtitle->lock, CX_THINLOCK_ID(cx));
|
||||||
}
|
}
|
||||||
|
@ -1350,6 +1350,10 @@ js_InitTitle(JSContext *cx, JSTitle *title)
|
||||||
void
|
void
|
||||||
js_FinishTitle(JSContext *cx, JSTitle *title)
|
js_FinishTitle(JSContext *cx, JSTitle *title)
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG_SCOPE_COUNT
|
||||||
|
js_unlog_title(title);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef JS_THREADSAFE
|
#ifdef JS_THREADSAFE
|
||||||
/* Title must be single-threaded at this point, so set ownercx. */
|
/* Title must be single-threaded at this point, so set ownercx. */
|
||||||
JS_ASSERT(title->u.count == 0);
|
JS_ASSERT(title->u.count == 0);
|
||||||
|
|
|
@ -174,11 +174,6 @@ js_NewScope(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops, JSClass *clasp,
|
||||||
return scope;
|
return scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_SCOPE_COUNT
|
|
||||||
extern void
|
|
||||||
js_unlog_scope(JSScope *scope);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined DEBUG || defined JS_DUMP_PROPTREE_STATS
|
#if defined DEBUG || defined JS_DUMP_PROPTREE_STATS
|
||||||
# include "jsprf.h"
|
# include "jsprf.h"
|
||||||
# define LIVE_SCOPE_METER(cx,expr) JS_LOCK_RUNTIME_VOID(cx->runtime,expr)
|
# define LIVE_SCOPE_METER(cx,expr) JS_LOCK_RUNTIME_VOID(cx->runtime,expr)
|
||||||
|
@ -189,10 +184,6 @@ js_unlog_scope(JSScope *scope);
|
||||||
void
|
void
|
||||||
js_DestroyScope(JSContext *cx, JSScope *scope)
|
js_DestroyScope(JSContext *cx, JSScope *scope)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_SCOPE_COUNT
|
|
||||||
js_unlog_scope(scope);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef JS_THREADSAFE
|
#ifdef JS_THREADSAFE
|
||||||
js_FinishTitle(cx, &scope->title);
|
js_FinishTitle(cx, &scope->title);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5530,7 +5530,10 @@ TraceRecorder::test_property_cache(JSObject* obj, LIns* obj_ins, JSObject*& obj2
|
||||||
JSAtom* atom;
|
JSAtom* atom;
|
||||||
JSPropCacheEntry* entry;
|
JSPropCacheEntry* entry;
|
||||||
PROPERTY_CACHE_TEST(cx, pc, aobj, obj2, entry, atom);
|
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.
|
// Miss: pre-fill the cache for the interpreter, as well as for our needs.
|
||||||
// FIXME: 452357 - correctly propagate exceptions into the interpreter from
|
// FIXME: 452357 - correctly propagate exceptions into the interpreter from
|
||||||
// js_FindPropertyHelper, js_LookupPropertyWithFlags, and elsewhere.
|
// js_FindPropertyHelper, js_LookupPropertyWithFlags, and elsewhere.
|
||||||
|
|
|
@ -210,7 +210,7 @@ JS_DumpHistogram(JSBasicStats *bs, FILE *fp)
|
||||||
|
|
||||||
#endif /* JS_BASIC_STATS */
|
#endif /* JS_BASIC_STATS */
|
||||||
|
|
||||||
#if defined DEBUG_notme && defined XP_UNIX
|
#if defined(DEBUG_notme) && defined(XP_UNIX)
|
||||||
|
|
||||||
#define __USE_GNU 1
|
#define __USE_GNU 1
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
@ -314,7 +314,7 @@ CallTree(void **bp)
|
||||||
return site;
|
return site;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSCallsite *
|
JS_FRIEND_API(JSCallsite *)
|
||||||
JS_Backtrace(int skip)
|
JS_Backtrace(int skip)
|
||||||
{
|
{
|
||||||
void **bp, **bpdown;
|
void **bp, **bpdown;
|
||||||
|
@ -342,4 +342,14 @@ JS_Backtrace(int skip)
|
||||||
return CallTree(bp);
|
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) */
|
||||||
|
|
|
@ -144,7 +144,7 @@ JS_DumpHistogram(JSBasicStats *bs, FILE *fp);
|
||||||
#endif /* JS_BASIC_STATS */
|
#endif /* JS_BASIC_STATS */
|
||||||
|
|
||||||
|
|
||||||
#ifdef XP_UNIX
|
#if defined(DEBUG_notme) && defined(XP_UNIX)
|
||||||
|
|
||||||
typedef struct JSCallsite JSCallsite;
|
typedef struct JSCallsite JSCallsite;
|
||||||
|
|
||||||
|
@ -159,7 +159,11 @@ struct JSCallsite {
|
||||||
void *handy;
|
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
|
#endif
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче