Closed Bug 1306008 Opened 9 years ago Closed 6 years ago

Investigate adding pre write barrier to JS::Heap<T>

Categories

(Core :: JavaScript: GC, defect, P3)

defect

Tracking

()

RESOLVED FIXED
mozilla68
Tracking Status
firefox68 --- fixed

People

(Reporter: jonco, Assigned: jonco)

References

Details

(Keywords: triage-deferred)

Attachments

(4 files)

Heap<T> currently has post barriers only as I think mostly these get marked as part of the root set. However this is not always the case, e.g. in DOMProxyHandler::GetAndClearExpandoObject there is a large comment and call to ExposeValueToActiveJS which could be avoided if we had this. Of course there may be other places where don't do this and need to.
Bug 1294747 added the ExposeValueToActiveJS in the case above.
Keywords: triage-deferred
Priority: -- → P3
Blocks: 1536061

This adds a pre write barrier to Heap<T> so that these can be uses as non-roots in the heap without breaking our snapshot at the beginning invariant if they are written to during an incremental GC. This makes it harder to misuse and allows us to take out manual barriers in at least one place.

Heap<JSObject*> is now equivalent to ObjectPtr so we can remove the latter.

Depends on D25083

Previously NPObjectMemberPrivate was allocated with malloc which bypassed Heap<T>'s constructors.

Depends on D25084

This call is not necessary now that Heap<T> has a pre-barrier which does this automatically.

Depends on D25085

I'll reply to sfink's review comments on here for visibility.

Is there a complete source of documentation on Heap<T> vs HeapPtr<T> vs GCPtr<T> vs TenuredHeap<T> vs bare T*? I never feel like I have a complete picture. It seems like the relevant dimensions include

Prebarriered?
Postbarriered?
Read barriered?
Movable?
Deletable outside of a GC?

...and I'm not sure what else. Oh, and I think the last two are only relevant for post-barriered things, since moving and deleting are only problematic if there could be pointers to them in a store buffer?

Following these patches JS::Heap<T> should be equivalent to js::HeapPtr<T>. The former is for external use and the latter is slightly more efficient (more stuff is inlined). They both have pre- and post-barriers, and are movable and deletable outside of a GC.

JS::TenuredHeap<T> is a more efficient Heap<T> for when you know you don't have a nursery pointer (it omits the post-barrier).

js::GCPtr<T> is internal and more efficient again, at the cost of not being movable or deletable outside of a GC.

I seem to frequently get into situations where I'm just not sure what to use. For example, consider PropertyDescriptor. Why does it use a bare JSObject*?

Good question. It looks like this is just a value and works in the same way as our tagged pointers - it must be used in Rooted<> if it's on the stack or HeapPtr<> if it's on the heap (if that ever happens).

(In reply to Jon Coppeard (:jonco) from comment #6)
Oh, I forgot that Heap<T> does gray unmarking / expose to active JS in the comment above. I guess I'll put this all in patch for bug 1539570.

Pushed by jcoppeard@mozilla.com: https://hg.mozilla.org/integration/mozilla-inbound/rev/2609de72b1d1 Give JS::Heap<T> pointer wrappers a pre-barrier r=sfink https://hg.mozilla.org/integration/mozilla-inbound/rev/4faf873bf48f Replace ObjectPtr with JS::Heap<JSObject*> r=sfink https://hg.mozilla.org/integration/mozilla-inbound/rev/31b14d077054 Use new to allocate NPObjectMemberPrivate r=mccr8 https://hg.mozilla.org/integration/mozilla-inbound/rev/92c43505695c Remove unnecessary expose call in DOMProxyHandler r=bzbarsky
Assignee: nobody → jcoppeard
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: