Closed Bug 1625212 Opened 6 years ago Closed 6 years ago

Investigate giving GC cells an explicit header field to store the GC flags

Categories

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

task

Tracking

()

RESOLVED FIXED
mozilla77
Tracking Status
firefox77 --- fixed

People

(Reporter: jonco, Assigned: jonco)

References

Details

Attachments

(13 files, 4 obsolete files)

47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review

The GC uses the bottom bits of the first word of a GC thing to store some flags, e.g. to tell if the thing has been forwarded. This is surprising to GC thing implementers who must take care not to clobber the flags when storing to this word. It is also possibly undefined behaviour, although I don't understand all the nuances around that.

To resolve this we could add a uintptr_t field to Cell (the ultimate base class of all GC things) and add accessors that allow derived classes to use the spare bits to store their data, with the appropriate assertions.

The flags_ word is factored out of CellWithLengthAndFlags and renamed flagsAndData_ for clarity. ObjectGroup is udpated to use the new class.

Shape is updated to use the new class.

Depends on D68420

Depends on D68421

Depends on D68422

Asking for feedback for whether you think this is sane and should land. I don't particularly like moving the first field out of the derived classes, but it's arguably still better than the status quo.

Flags: needinfo?(sphink)
Flags: needinfo?(jdemooij)

Another design angle here is to leave the field in the current place, but put wrapper types around the pointers to at least document it all. So for BaseScript, we would replace uint8_t* jitCodeRaw_ with CellHeaderNonGcPtr<uint8_t> jitCodeRaw_. I have no idea what to call that though..

(In reply to Ted Campbell [:tcampbell] from comment #6)
That works and the reason I didn't do that is because it doesn't enforce that first word of the cell actually uses one of these wrapper types. Perhaps there is a solution to that though.

(In reply to Jon Coppeard (:jonco) from comment #7)

because it doesn't enforce that first word of the cell actually uses one of these wrapper types. Perhaps there is a solution to that though.

Maybe something like this?

template <typename T>
void Check(T* thing) {
  auto t = thing->firstWordRef(); // Every Cell type needs to implement this.
  static_assert decltype(t) is approved;
  MOZ_ASSERT(&t == thing, "must be first member");
}

(In reply to Jan de Mooij [:jandem] from comment #8)
Yeah, exactly what I had in mind :)

Flags: needinfo?(sphink)
Flags: needinfo?(jdemooij)

I guess if we go this route we can consider making CellWithLengthAndFlags just a member instead of a base.

Summary: Investigate storing GC cell flags in a field in the base class → Investigate giving GC cells an explicit header field to store the GC flags
Attachment #9136048 - Attachment is obsolete: true
Attachment #9136049 - Attachment is obsolete: true
Attachment #9136050 - Attachment is obsolete: true
Attachment #9136051 - Attachment is obsolete: true

Sorry for not getting to this. At this point, I guess I'll just say that I do prefer not pulling out the field, since it seems like it's avoidable without losing the checking.

As for UB, specifically strict aliasing considerations, I don't think these changes are going to really affect anything. I've been reading up on aliasing rules, and I think we do have a problem already, but it's going to need to be fixed at the read/write sites; uintptr_t isn't going to help.

For example, I think https://searchfox.org/mozilla-central/rev/9c6e7500c0015a2c60be7b1b888261d95095ce27/js/src/gc/Marking-inl.h#125 is writing a uintptr_t into a memory location that c++ says has DynamicType JitCode* or ObjectGroup* or whatever, and thus smells like a strict aliasing violation to me. IIUC, that should be doing a placement new. Same with https://searchfox.org/mozilla-central/rev/9c6e7500c0015a2c60be7b1b888261d95095ce27/js/src/gc/Marking.cpp#3161,3163 . I think that if those things were done, https://searchfox.org/mozilla-central/rev/9c6e7500c0015a2c60be7b1b888261d95095ce27/js/src/gc/RelocationOverlay.h#51 would become correct. (Or rather, that line is correct no matter what, since it's just returning a pointer. The UB would be when something dereferences it.)

Then there's https://searchfox.org/mozilla-central/rev/9c6e7500c0015a2c60be7b1b888261d95095ce27/js/src/gc/Cell.h#171-172 which does the big bad thing of dereferencing a pointer with the wrong type. I think this would be the correct code:

  inline bool isForwarded() const {
    uintptr_t firstWord;
    memcpy(&firstWord, reinterpret_cast<void*>(this), sizeof(uintptr_t));
    return firstWord & FORWARD_BIT;
  }

(and supposedly that's supposed to compile down to the same thing; I haven't checked.) firstWord points to memory that is and always will be a uintptr_t. this points to memory that might have a bunch of different types, but memcpy is allowed to read from anything.

If it helps, and people don't tell me I'm barking mad, I could put together a patch for this stuff on top of whatever you come up with here, since it'll probably change some of this(?). (Or you can do it if you prefer.)

(In reply to Steve Fink [:sfink] [:s:] from comment #11)
The goal here is to replace underlying pointer field (e.g. the JitCode* or ObjectGroup*) with a uintptr_t in one way or another to avoid reading/writing the field with the wrong type. AIUI this solves the problem for the forwarding flag and address, but not the ReloationOverlay::next_ field. The possibility of using placement new for this was discussed.

Depends on D68831

Depends on D68832

I had a compilation issue with making the cell header contain a scope pointer due to the Scope class not being fully defined at that point so I worked around it by reodering the fields.

Depends on D68833

Depends on D68834

I had to reorder the fields here to make so the first field was simple to replace.

Depends on D68836

Depends on D68837

Depends on D68838

Pushed by jcoppeard@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/c4c240f9d3e1 Introduce CellHeader base class and convert String and BigInt to use an explicit cell header field r=tcampbell https://hg.mozilla.org/integration/autoland/rev/e1350f5a444c Add CellHeaderWithNonGCPointer class and use it for ObjectGroup r=sfink https://hg.mozilla.org/integration/autoland/rev/b8850cec94f9 Add CellHeaderWithTenuredGCPointer and use it for Shape r=sfink https://hg.mozilla.org/integration/autoland/rev/5c1db656c7a6 Give JitCode a CellHeader r=jandem,tcampbell https://hg.mozilla.org/integration/autoland/rev/d02c04d34ed9 Give JSScript a cell header r=tcampbell https://hg.mozilla.org/integration/autoland/rev/e38411544a17 Give Scope a cell header r=jandem https://hg.mozilla.org/integration/autoland/rev/629b473b36f2 Give JSObject a cell header r=jandem https://hg.mozilla.org/integration/autoland/rev/51a9e5d36bfb Give RegExpShared a cell header r=sfink https://hg.mozilla.org/integration/autoland/rev/bf0a5676af9f Give Symbol a cell header r=tcampbell https://hg.mozilla.org/integration/autoland/rev/a255c4445189 Give BaseShape a cell header r=tcampbell https://hg.mozilla.org/integration/autoland/rev/9ac72a058642 Check that all cells have a cell header and that it is at the start of the cell r=sfink
Regressions: 1626578
Regressions: 1626631
Backout by rgurzau@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/0a07f96b0b41 Backed out 11 changesets for mochitest failures at Cell.h on a CLOSED TREE.

Previously this ended up with MovingTracer doing the update itself, but now the pointer is stored in a CellHeader it's done through an overload of TraceEdge.

The TSAN stack doesn't appear to have the class for the unsafeSetPtr method that actually does the update so rather than make this apply to all uses of this method I added a supression for the next function up in the stack.

Blocks: 1627248
Pushed by jcoppeard@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/dd3c63762d2c Introduce CellHeader base class and convert String and BigInt to use an explicit cell header field r=tcampbell https://hg.mozilla.org/integration/autoland/rev/90a41b1fa6e0 Add CellHeaderWithNonGCPointer class and use it for ObjectGroup r=sfink https://hg.mozilla.org/integration/autoland/rev/8fecdcf14ec5 Add CellHeaderWithTenuredGCPointer and use it for Shape r=sfink https://hg.mozilla.org/integration/autoland/rev/219873fae1dc Give JitCode a CellHeader r=jandem,tcampbell https://hg.mozilla.org/integration/autoland/rev/c846189c425c Give JSScript a cell header r=tcampbell https://hg.mozilla.org/integration/autoland/rev/d12afb36d200 Give Scope a cell header r=jandem https://hg.mozilla.org/integration/autoland/rev/a0531e0c35f4 Give JSObject a cell header r=jandem https://hg.mozilla.org/integration/autoland/rev/42aacd19ea36 Give RegExpShared a cell header r=sfink https://hg.mozilla.org/integration/autoland/rev/366364315e61 Give Symbol a cell header r=tcampbell https://hg.mozilla.org/integration/autoland/rev/a1cc6e73479e Give BaseShape a cell header r=tcampbell https://hg.mozilla.org/integration/autoland/rev/6de2c3884377 Check that all cells have a cell header and that it is at the start of the cell r=sfink https://hg.mozilla.org/integration/autoland/rev/ea5efdc9ae7a Update gdb pretty printers in line with CellHeader changes r=sfink https://hg.mozilla.org/integration/autoland/rev/cfa64a6b5a87 Update TSAN supression list now a Shape's base shape is not marked directly r=sfink
Flags: needinfo?(jcoppeard)
Regressions: 1627683
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: