Closed Bug 704258 Opened 13 years ago Closed 12 years ago

"Assertion failure: static_cast<Cell *>(thing)->isMarked()" with adoptNode, gczeal(4)

Categories

(Core :: JavaScript Engine, defect)

x86_64
macOS
defect
Not set
critical

Tracking

()

RESOLVED WORKSFORME

People

(Reporter: jruderman, Assigned: billm)

References

Details

(Keywords: assertion, testcase)

Attachments

(3 files, 1 obsolete file)

1. Install https://www.squarefree.com/extensions/domFuzzLite3.xpi
2. Load the testcase

Result:

Assertion failure: static_cast<Cell *>(thing)->isMarked(), at js/src/jsgc.cpp:3572
Attached file stack trace
Assignee: general → wmccloskey
Attached patch fix (obsolete) — Splinter Review
Excellent test! I strongly suspected that ReparentWrapperIfFound was not being barriered correctly, but I didn't know how to test it. This is exactly what I was looking for. Jesse, is there a way we could add this to the test suite (maybe Mochitests)?

The problem was that the trace hook for a wrapped native works pretty much as follows:
  TraceScopeJSObjects(trc, wrapper->GetScope());
What I didn't realize is that GetScope() doesn't directly access a field. Instead, it often does GetProto()->GetScope(). This means that if the proto of a wrapped native changes, then its scope is often changing as well. This patch marks the scope as well as the proto whenever the proto is changed.
Attachment #579786 - Flags: review?(luke)
I'm not very familiar with Mochitest, but it has something called "SpecialPowers" that you can probably use. It's similar to my extension's "fuzzPriv".
Attached patch patch v2Splinter Review
The previous patch was based off the incremental GC branch. This one should apply to m-c.

Bobby, this is the write barrier patch we talked about. It makes the write barrier code a little more explicit.
Attachment #579786 - Attachment is obsolete: true
Attachment #579786 - Flags: review?(luke)
Attachment #581018 - Flags: review?(bobbyholley+bmo)
Comment on attachment 581018 [details] [diff] [review]
patch v2

>+    void writeBarrierPre(JSRuntime *rt) {
>+        JS_ModifyReference((void **) &value, value);
>+    }

It's not immediately clear to me why this is called "writeBarrierPre". Why not writeBarrier?

>-    if (JS_GetIncrementalGCTracer(rt))
>+    if (JS_IsWriteBarrierNeeded(rt))
>         mScriptableInfo->Mark();

>     // Write barrier for incremental GC.
>     if (HasProto()) {
>         JSRuntime* rt = GetRuntime()->GetJSRuntime();
>-        if (JS_GetIncrementalGCTracer(rt))
>-            GetProto()->TraceJS(JS_GetIncrementalGCTracer(rt));
>+        GetProto()->WriteBarrier(rt);

It would be nice if we could be consistent about whether we want to do this kind of "arms-length" check. Is the situation such that we don't want to call Mark() on an XPCNativeScriptable when we're not in an incremental marking period? If so, it looks like the call to GetProto->WriteBarrier() is going to do just that (see the bottom of the patch).

>+    void WriteBarrier(JSRuntime *rt)
>+    {
>+        mGlobalJSObject.writeBarrierPre(rt);
>+        if (mPrototypeJSObject.get())
>+            mPrototypeJSObject.writeBarrierPre(rt);
>+        if (mPrototypeJSFunction.get())
>+            mPrototypeJSFunction.writeBarrierPre(rt);
>+    }
>+

It seems silly to have to check whether the pointer is null all the time. Can we make writeBarrier a no-op on null heap pointers and remove the checks?
Attachment #581018 - Flags: review?(bobbyholley+bmo)
This no longer reproduces with incremental GC landing. I remember realizing a while ago that this bug was actually a problem where the write barrier verifier asserted even though nothing was actually wrong. The verifier has changed a lot since then, so hopefully this is fixed.
Status: NEW → RESOLVED
Closed: 12 years ago
Resolution: --- → WORKSFORME
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: