GC can leave GSN cache pointing to destroyed script

RESOLVED FIXED in mozilla1.9alpha1

Status

()

Core
JavaScript Engine
P1
normal
RESOLVED FIXED
11 years ago
11 years ago

People

(Reporter: Igor Bukanov, Assigned: brendan)

Tracking

({fixed1.8.1.1})

Trunk
mozilla1.9alpha1
fixed1.8.1.1
Points:
---
Dependency tree / graph
Bug Flags:
blocking1.8.1.1 +
in-testsuite -

Firefox Tracking Flags

(Not tracked)

Details

Attachments

(1 attachment, 4 obsolete attachments)

(Reporter)

Description

11 years ago
[ This is trunk-only regression and spin-off of bug 347306 comment 20].

The patch for bug 347306 contains:

> #ifdef JS_THREADSAFE
>     /*
>      * Set all thread local freelists to NULL. We may visit a thread's
>      * freelist more than once. To avoid redundant clearing we unroll the
>      * current thread's step.
>+     *
>+     * Also, in case a JSScript wrapped in an object was finalized, we clear
>+     * the acx->gsnCache.script pointer and finish the cache's hashtable.
>      */
>     memset(cx->thread->gcFreeLists, 0, sizeof cx->thread->gcFreeLists);
>     iter = NULL;
>     while ((acx = js_ContextIterator(rt, JS_FALSE, &iter)) != NULL) {
>         if (!acx->thread || acx->thread == cx->thread)
>             continue;
>         memset(acx->thread->gcFreeLists, 0, sizeof acx->thread->gcFreeLists);
>+        JS_CLEAR_GSN_CACHE(acx);
>     }
> #endif

If there are more JSContext associated with the current thread besides the current one with GSN cache, then the loop will leave the caches uncleared. Thus they may point to a destroyed JSScript instance.
(Assignee)

Comment 1

11 years ago
Created attachment 246203 [details] [diff] [review]
fix
Assignee: general → brendan
Status: NEW → ASSIGNED
Attachment #246203 - Flags: review?(igor.bukanov)
(Assignee)

Comment 2

11 years ago
Need this to land the patch for bug 357306 on the 1.8 branch, and for js1.7src.

/be
Blocks: 355044
Priority: -- → P1
Target Milestone: --- → mozilla1.9alpha
(Reporter)

Comment 3

11 years ago
Comment on attachment 246203 [details] [diff] [review]
fix

>--- jsgc.c	27 Oct 2006 19:38:33 -0000	3.180
>+++ jsgc.c	21 Nov 2006 21:50:36 -0000
>@@ -2819,19 +2819,23 @@ js_GC(JSContext *cx, JSGCInvocationKind 
> #endif
> 
> #ifdef JS_THREADSAFE
>     /*
>      * Set all thread local freelists to NULL. We may visit a thread's
>      * freelist more than once. To avoid redundant clearing we unroll the
>      * current thread's step.
>      *
>-     * Also, in case a JSScript wrapped in an object was finalized, we clear
>-     * the acx->gsnCache.script pointer and finish the cache's hashtable.
>+     * Also, in case a JSScript wrapped within an object was finalized, we
>+     * null acx->thread->gsnCache.script and finish the cache's hashtable.
>+     * Note that js_DestroyScript, called from script_finalize, will have
>+     * already cleared cx->thread->gsnCache above during finalization, so we
>+     * don't have to here.
>      */
>+    JS_ASSERT(!cx->thread->gsnCache.script);
>     memset(cx->thread->gcFreeLists, 0, sizeof cx->thread->gcFreeLists);
>     iter = NULL;
>     while ((acx = js_ContextIterator(rt, JS_FALSE, &iter)) != NULL) {
>         if (!acx->thread || acx->thread == cx->thread)
>             continue;
>         memset(acx->thread->gcFreeLists, 0, sizeof acx->thread->gcFreeLists);
>         JS_CLEAR_GSN_CACHE(acx);
>     }

This does not cover single-threaded case. For a minimal patch why not just move the cache nullifier code into the general context marking loop in js_GC and just do it there when acx != cx ?
Attachment #246203 - Flags: review?(igor.bukanov) → review-
(Assignee)

Comment 4

11 years ago
Good idea -- also, the patch for bug 361451 provokes the question: why sweep atoms before objects, rather than after (as property tree nodes and script filenames are done)?

/be
(Assignee)

Comment 5

11 years ago
Created attachment 246338 [details] [diff] [review]
fix, v2

mrbkap, please feel free to review too.

/be
Attachment #246338 - Flags: review?(igor.bukanov)
(Assignee)

Comment 6

11 years ago
Comment on attachment 246338 [details] [diff] [review]
fix, v2

Whoops, wrong bug.

/be
Attachment #246338 - Attachment is obsolete: true
Attachment #246338 - Flags: review?(igor.bukanov)
(Assignee)

Comment 7

11 years ago
Created attachment 246342 [details] [diff] [review]
fix, v2
Attachment #246203 - Attachment is obsolete: true
Attachment #246342 - Flags: review?(igor.bukanov)
(Reporter)

Comment 8

11 years ago
Comment on attachment 246342 [details] [diff] [review]
fix, v2

>+#else
>+    /*
>+     * The thread-unsafe case just has to clear each context's GSN cache,
>+     * except for cx's of course (see previous comment).
>+     */
>+    while ((acx = js_ContextIterator(rt, JS_FALSE, &iter)) != NULL) {
>+        if (acx == cx)
>+            continue;
>+        JS_CLEAR_GSN_CACHE(acx);
>+    }
> #endif

This is very different behaviour between single and multi threaded cases. Why not to store the cache in the runtime when JS_THREADSAFE is not defined?
(Assignee)

Comment 9

11 years ago
Created attachment 246417 [details] [diff] [review]
fix, v3

Hope the single-threaded fill/hit-repeatedly-on-one-thread pattern is the common case, with no cache thrashing among contexts.

/be
Attachment #246342 - Attachment is obsolete: true
Attachment #246417 - Flags: review?(igor.bukanov)
Attachment #246342 - Flags: review?(igor.bukanov)
(Reporter)

Updated

11 years ago
Attachment #246417 - Flags: review?(igor.bukanov) → review+
(Assignee)

Comment 10

11 years ago
Fixed on trunk:

Checking in jscntxt.h;
/cvsroot/mozilla/js/src/jscntxt.h,v  <--  jscntxt.h
new revision: 3.127; previous revision: 3.126
done
Checking in jsgc.c;
/cvsroot/mozilla/js/src/jsgc.c,v  <--  jsgc.c
new revision: 3.184; previous revision: 3.183
done
Checking in jsscript.c;
/cvsroot/mozilla/js/src/jsscript.c,v  <--  jsscript.c
new revision: 3.122; previous revision: 3.121
done

/be
Status: ASSIGNED → RESOLVED
Last Resolved: 11 years ago
Resolution: --- → FIXED
This patch seems to have caused the current tinderbox orange.
The stack to the crash and assertion failures that I see locally with that patch applied are at http://pastebin.mozilla.org/1539.
(Assignee)

Comment 13

11 years ago
Backed out, completely botched the initialization of JSThread.gsnCache.  Revised patch soon.

/be
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
(Assignee)

Updated

11 years ago
Status: REOPENED → ASSIGNED
(Assignee)

Comment 14

11 years ago
Created attachment 246451 [details] [diff] [review]
fix, v4

Sorry for the blunder -- this works in my Firefox build.

/be
Attachment #246417 - Attachment is obsolete: true
Attachment #246451 - Flags: review?(igor.bukanov)
(Reporter)

Updated

11 years ago
Attachment #246451 - Flags: review?(igor.bukanov) → review+
(Assignee)

Comment 15

11 years ago
Checking in jsapi.c;
/cvsroot/mozilla/js/src/jsapi.c,v  <--  jsapi.c
new revision: 3.290; previous revision: 3.289
done
Checking in jscntxt.c;
/cvsroot/mozilla/js/src/jscntxt.c,v  <--  jscntxt.c
new revision: 3.94; previous revision: 3.93
done
Checking in jscntxt.h;
/cvsroot/mozilla/js/src/jscntxt.h,v  <--  jscntxt.h
new revision: 3.129; previous revision: 3.128
done
Checking in jsgc.c;
/cvsroot/mozilla/js/src/jsgc.c,v  <--  jsgc.c
new revision: 3.187; previous revision: 3.186
done
Checking in jsscript.c;
/cvsroot/mozilla/js/src/jsscript.c,v  <--  jsscript.c
new revision: 3.124; previous revision: 3.123
done

/be
Status: ASSIGNED → RESOLVED
Last Resolved: 11 years ago11 years ago
Resolution: --- → FIXED

Updated

11 years ago
Flags: in-testsuite-
Blocks: 347306
No longer depends on: 347306
blocking 1.8.1.1 because it's a regression from a 1.8.1.1-blocking bug (for verification testing purposes).
No longer blocks: 347306
Depends on: 347306
Flags: blocking1.8.1.1+
Blocks: 347306
No longer depends on: 347306
(Assignee)

Updated

11 years ago
Keywords: fixed1.8.1.1
You need to log in before you can comment on or make changes to this bug.