WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
223629
[JSC] Functor for WeakGCMap::ensureValue must not invoke GC
https://bugs.webkit.org/show_bug.cgi?id=223629
Summary
[JSC] Functor for WeakGCMap::ensureValue must not invoke GC
Yusuke Suzuki
Reported
2021-03-23 01:42:15 PDT
[JSC] Functor for WeakGCMap::ensureValue must not invoke GC
Attachments
Patch
(5.86 KB, patch)
2021-03-23 01:45 PDT
,
Yusuke Suzuki
no flags
Details
Formatted Diff
Diff
Patch
(7.93 KB, patch)
2021-03-23 01:53 PDT
,
Yusuke Suzuki
mark.lam
: review+
ews-feeder
: commit-queue-
Details
Formatted Diff
Diff
Patch
(11.13 KB, patch)
2021-03-23 11:49 PDT
,
Yusuke Suzuki
no flags
Details
Formatted Diff
Diff
Show Obsolete
(1)
View All
Add attachment
proposed patch, testcase, etc.
Yusuke Suzuki
Comment 1
2021-03-23 01:45:43 PDT
Created
attachment 423997
[details]
Patch
Yusuke Suzuki
Comment 2
2021-03-23 01:45:46 PDT
<
rdar://problem/75619217
>
Yusuke Suzuki
Comment 3
2021-03-23 01:48:17 PDT
Comment on
attachment 423997
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=423997&action=review
> Source/JavaScriptCore/runtime/WeakGCMap.h:73 > + // If functor invokes GC, GC can prune WeakGCMap, and manipulate HashMap while we are touching it in ensure function. > + // The functor must not invoke GC. > + DisallowGC disallowGC;
I do not want to put DeferGC here since we would like to be aware about the scope of DeferGC explicitly. Deferring GC is not generally good. We would like to invoke GC responsively. If we use DeferGC, we should make DeferGC scope small, and we should be aware of that.
Yusuke Suzuki
Comment 4
2021-03-23 01:53:22 PDT
Created
attachment 423998
[details]
Patch
Mark Lam
Comment 5
2021-03-23 08:06:49 PDT
Comment on
attachment 423998
[details]
Patch r=me. Please make sure that the EWS failures are not real. FYI, I've started a re-run.
Darin Adler
Comment 6
2021-03-23 09:14:10 PDT
Instead of deferring GC we can switch to a double hashing algorithm (separate get and add), or we can make code that conditionally rehashes if the hash table is modified during the ensure functor.
Sam Weinig
Comment 7
2021-03-23 09:22:41 PDT
It's too bad we can't reuse any of the logic in WeakMapImpl for this, which already should have to deal with this issue.
Sam Weinig
Comment 8
2021-03-23 09:25:52 PDT
(In reply to Sam Weinig from
comment #7
)
> It's too bad we can't reuse any of the logic in WeakMapImpl for this, which > already should have to deal with this issue.
There is very similar code to this in JSDOMGlobalObject::createCrossOriginFunction/JSDOMGlobalObject::createCrossOriginGetterSetter. We should make sure that case is also fixed and potentially add a test if possible.
Sam Weinig
Comment 9
2021-03-23 09:46:35 PDT
(In reply to Yusuke Suzuki from
comment #3
)
> Comment on
attachment 423997
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=423997&action=review
> > > Source/JavaScriptCore/runtime/WeakGCMap.h:73 > > + // If functor invokes GC, GC can prune WeakGCMap, and manipulate HashMap while we are touching it in ensure function. > > + // The functor must not invoke GC. > > + DisallowGC disallowGC; > > I do not want to put DeferGC here since we would like to be aware about the > scope of DeferGC explicitly. Deferring GC is not generally good. We would > like to invoke GC responsively. > If we use DeferGC, we should make DeferGC scope small, and we should be > aware of that.
Would it work to instead of using DeferGC for this, we added a bit to WeakGCMap that makes pruneStaleEntries() a no-op while it is set? And then a function like ensureValue would set that bit while it was running?
Mark Lam
Comment 10
2021-03-23 09:53:25 PDT
(In reply to Sam Weinig from
comment #9
)
> (In reply to Yusuke Suzuki from
comment #3
) > > Comment on
attachment 423997
[details]
> > Patch > > > > View in context: > >
https://bugs.webkit.org/attachment.cgi?id=423997&action=review
> > > > > Source/JavaScriptCore/runtime/WeakGCMap.h:73 > > > + // If functor invokes GC, GC can prune WeakGCMap, and manipulate HashMap while we are touching it in ensure function. > > > + // The functor must not invoke GC. > > > + DisallowGC disallowGC; > > > > I do not want to put DeferGC here since we would like to be aware about the > > scope of DeferGC explicitly. Deferring GC is not generally good. We would > > like to invoke GC responsively. > > If we use DeferGC, we should make DeferGC scope small, and we should be > > aware of that. > > Would it work to instead of using DeferGC for this, we added a bit to > WeakGCMap that makes pruneStaleEntries() a no-op while it is set? And then a > function like ensureValue would set that bit while it was running?
if GC can run, and the setter is not reachable by GC, and we don't prune the pointer, wouldn't simply skipping pruning means we'll get a dangling pointer because GC can sweep that setter away later?
Mark Lam
Comment 11
2021-03-23 09:55:35 PDT
(In reply to Mark Lam from
comment #10
)
> if GC can run, and the setter is not reachable by GC, and we don't prune the > pointer, wouldn't simply skipping pruning means we'll get a dangling pointer > because GC can sweep that setter away later?
Nevermind, I misunderstood pruning. The pointer is already null.
Yusuke Suzuki
Comment 12
2021-03-23 11:44:44 PDT
(In reply to Darin Adler from
comment #6
)
> Instead of deferring GC we can switch to a double hashing algorithm > (separate get and add), or we can make code that conditionally rehashes if > the hash table is modified during the ensure functor.
I think the current DeferGC thing is the best way since, 1. DeferGC does not defer GC forever. When destroying DeferGC scope, we invoke GC if GC request happened during DeferGC scope. So this DeferGC only defers one function allocation. 2. While we can just defer GC for one allocation, we can avoid double hashing, and we can avoid making hash table more complicated.
Yusuke Suzuki
Comment 13
2021-03-23 11:46:34 PDT
(In reply to Sam Weinig from
comment #9
)
> (In reply to Yusuke Suzuki from
comment #3
) > > Comment on
attachment 423997
[details]
> > Patch > > > > View in context: > >
https://bugs.webkit.org/attachment.cgi?id=423997&action=review
> > > > > Source/JavaScriptCore/runtime/WeakGCMap.h:73 > > > + // If functor invokes GC, GC can prune WeakGCMap, and manipulate HashMap while we are touching it in ensure function. > > > + // The functor must not invoke GC. > > > + DisallowGC disallowGC; > > > > I do not want to put DeferGC here since we would like to be aware about the > > scope of DeferGC explicitly. Deferring GC is not generally good. We would > > like to invoke GC responsively. > > If we use DeferGC, we should make DeferGC scope small, and we should be > > aware of that. > > Would it work to instead of using DeferGC for this, we added a bit to > WeakGCMap that makes pruneStaleEntries() a no-op while it is set? And then a > function like ensureValue would set that bit while it was running?
I think DeferGC is better since this makes collecting dead Weak handles & shrinking later. When comparing (1) not collecting dead Weak handles until the next Full GC and (2) defer GC for one function allocation, (2) is better.
Yusuke Suzuki
Comment 14
2021-03-23 11:47:53 PDT
(In reply to Sam Weinig from
comment #8
)
> (In reply to Sam Weinig from
comment #7
) > > It's too bad we can't reuse any of the logic in WeakMapImpl for this, which > > already should have to deal with this issue. > > There is very similar code to this in > > JSDOMGlobalObject::createCrossOriginFunction/JSDOMGlobalObject:: > createCrossOriginGetterSetter. > > We should make sure that case is also fixed and potentially add a test if > possible.
I think the existing test is failing because of DisallowGC, and this ensures that we are not invoking GC which incurs WeakGCMap modification. So crashing tests are guaranteeing this.
Yusuke Suzuki
Comment 15
2021-03-23 11:49:16 PDT
Created
attachment 424043
[details]
Patch
Yusuke Suzuki
Comment 16
2021-03-23 16:36:44 PDT
Committed
r274911
(
235681@main
): <
https://commits.webkit.org/235681@main
>
Darin Adler
Comment 17
2021-03-23 16:54:41 PDT
Why are we deferring *both* at all call sites of ensureValue *and* inside ensureValue? It seems like we are holding up our pants using both belts and suspenders. There is probably a good reason, but I can’t figure it out from reading the comments.
Yusuke Suzuki
Comment 18
2021-03-24 02:16:08 PDT
(In reply to Darin Adler from
comment #17
)
> Why are we deferring *both* at all call sites of ensureValue *and* inside > ensureValue? It seems like we are holding up our pants using both belts and > suspenders. There is probably a good reason, but I can’t figure it out from > reading the comments.
No, inside ensureValue we are using DisallowGC, not DeferGC.
Darin Adler
Comment 19
2021-03-24 10:29:46 PDT
(In reply to Yusuke Suzuki from
comment #18
)
> No, inside ensureValue we are using DisallowGC, not DeferGC.
I see. Let me check my understanding: callers must not GC-allocate in the function they pass to ensureValue, unless they discover they must, in which case they can relax the restriction by doing DeferGC.
Yusuke Suzuki
Comment 20
2021-03-24 14:13:49 PDT
(In reply to Darin Adler from
comment #19
)
> (In reply to Yusuke Suzuki from
comment #18
) > > No, inside ensureValue we are using DisallowGC, not DeferGC. > > I see. Let me check my understanding: callers must not GC-allocate in the > function they pass to ensureValue, unless they discover they must, in which > case they can relax the restriction by doing DeferGC.
Right. This enforces the caller to be aware that they are deferring GC while running this code.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug