Closed Bug 388070 Opened 18 years ago Closed 17 years ago

MMgc doesn't trace pointers to subobjects of an allocation

Categories

(Tamarin Graveyard :: Virtual Machine, defect)

defect
Not set
normal

Tracking

(Not tracked)

VERIFIED FIXED

People

(Reporter: jorendorff, Assigned: jorendorff)

References

Details

Attachments

(2 files, 2 obsolete files)

In file GC.cpp, function void GC::MarkItem(GCWorkItem &wi, GCStack<GCWorkItem> &work), lines 2112-2117: 2112 // make sure this is a pointer to the beginning 2113 2114 int itemNum = GCAlloc::GetIndex(block, item); 2115 2116 if(block->items + itemNum * block->size != item) 2117 continue; Here |item| is a value, found in pointer-containing memory, that might be a pointer to an allocation. By this point in the loop, we've already confirmed that |item| points into a GCBlock. What lines 2116-2117 do is *ignore* this pointer if it appears to point into the middle of an allocation. This will cause us trouble using MMgc for XPCOM, because XPCOM classes often multiple inheritance. I think replacing lines 2116-2117 with an assignment would be enough: 2116 item = block->items + itemNum * block->size; 2117 Not sure how this would affect performance for you, though; maybe an #ifdef would be better.
Blocks: 393034
Attached patch v1 (obsolete) — Splinter Review
This patch causes GC::MarkItem to treat a pointer into an allocation (at an offset) as a reference to that allocation. It also changes DWB to accept interior pointers. This costs an extra GC::FindBeginning() call in the slow path. In the fast path you don't get that far. I think that's as far as Mozilla needs to go. The patch doesn't change any other public methods, like GC::GetMark() or GC::IsWhite(), to accept interior pointers. It doesn't change DRC/DRCWB smart pointers to accept interior pointers either.
Assignee: nobody → jorendorff
Status: NEW → ASSIGNED
Attachment #280497 - Flags: review?
Attachment #280497 - Flags: review? → review?(treilly)
Here's an updated version that conditionally compiles in interior-pointer support. (The patch changes the cross-platform build to use MMGC_INTERIOR_PTRS; that could be an option to configure.py instead, if desired.)
Attachment #280497 - Attachment is obsolete: true
Attachment #281363 - Flags: review?(treilly)
Attachment #280497 - Flags: review?(treilly)
OS: Mac OS X → All
Hardware: PC → All
Transfer Bug from Core->Tamarin to Tamarin Product.
Component: Tamarin → Virtual Machine
Product: Core → Tamarin
jorendorff: In this page http://wiki.mozilla.org/Talk:XPCOMGC , there is a proposal for exact incremental GC concept. There is also a proposal to solve this bug by a 'Visitor' design pattern application.
Sergey, I don't think this would work. Casting to (void *) does not convert an interior pointer to a pointer-to-the-full-object. Try it out. As far as I know, casting a T* to void* doesn't change any bits of the pointer. The language requires that casting back to T* should produce the same pointer you started with; i.e. that pointers should "round-trip" to void* and back.
Actually, if you have a polymorphic object (with a vtable), dynamic_cast<void*> will return a pointer to the most-derived object, without knowing the type and without requiring RTTI.
(In reply to comment #5) > Sergey, I don't think this would work. Casting to (void *) does not convert an > interior pointer to a pointer-to-the-full-object. Try it out. I definitely agree with this. But I propose to convert *this* pointer to (void *) which should produce the same result each time. I'll check this out now.
Attached file test for (void *) this
I am getting this output: $ ./test i=804a008, a=804a008, b=804a00c, c=804a008, xa=804a008, xb=804a008 A B
Oh, OK, my apologies -- I just didn't see what you meant. Yes, that part will work fine. There are other parts of your GC scheme that I don't understand, though (see comments on the wiki page).
Comment on attachment 281363 [details] [diff] [review] v2 - same as v1 but using #ifdef MMGC_INTERIOR_PTRS Nothing obviously wrong with the "#else" code, or the new MMGC_INTERIOR_PTRS code. good to get treilly to review as well.
Attachment #281363 - Flags: review+
(In reply to comment #10) Thanks very much, Ed. I will wait for treilly's r+ before checking this in, unless I hear otherwise. Brendan asked me to check with you that we really want this in an #ifdef. I'd be happy either way. Code without #ifdefs gets better testing and is easier to maintain; but I think given the uncertainty, it might also make sense to check in with the #ifdef, then do measurements and see if it's OK to remove it.
I think I want to make another change to this patch before checking it in. v2 of the patch inserts an additional FindBeginning() call into the write barrier. Now I think it should be the mutator's responsibility to produce a pointer to the beginning of the referent. So that part of the patch should be dropped. With this change, DWB() would *not* support interior pointers, even in an MMGC_INTERIOR_PTRS build. Our nsCOMPtr smart pointers would need a slightly different write barrier than DWB() provides, but that's a good thing-- only COM pointers would incur the overhead of the extra FindBeginning call. And I think we can avoid calling FindBeginning() even from nsCOMPtr. Instead of using MMgc's bookkeeping to find the beginning of the object, we can use dynamic_cast<void *>.
(In reply to comment #12) Sounds good Jason, I'll keep my eye out for v3 and review that? In response to Brendan's plea to go w/o ifdefs I generally agree but don't want to introduce unnecessary changes into how the flash player works. It might not introduce any problems but the amount of testing required to make that assumption would be large. Instead I'd like to think about having a dynamic per-object mechanism for allowing interior pointers so we can support the functionality w/o ifdefs.
Attached patch v3Splinter Review
Here's the updated patch. Sorry for the delay--MMGC_THREADSAFE work intervened.
Attachment #281363 - Attachment is obsolete: true
Attachment #290229 - Flags: review?(treilly)
Attachment #281363 - Flags: review?(treilly)
Attachment #290229 - Flags: review?(treilly) → review+
Pushed change a4259e008469 to tamarin-central. treilly: Instead of #ifdef-ing, we could make this a runtime option, "bool interiorPointers;", false by default. The performance cost for Flash Player should be really tiny: the cost of "if (!interiorPointers)" times the rate of false positives that look like interior pointers. I'll file a new bug if there's any interest.
Status: ASSIGNED → RESOLVED
Closed: 17 years ago
Resolution: --- → FIXED
Depends on: 409014
You're probably right but I'd rather not rely on branch prediction for such a super critical hot spot.
Status: RESOLVED → VERIFIED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: