Bug 206726 - [JSC] DFG OSR exit is not marking CodeBlock::m_hasLinkedOSRExit when the exit target is checkpoint
Summary: [JSC] DFG OSR exit is not marking CodeBlock::m_hasLinkedOSRExit when the exit...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: New Bugs (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Yusuke Suzuki
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2020-01-23 20:51 PST by Yusuke Suzuki
Modified: 2020-01-23 22:09 PST (History)
7 users (show)

See Also:


Attachments
Patch (8.51 KB, patch)
2020-01-23 21:01 PST, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (8.54 KB, patch)
2020-01-23 21:06 PST, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (4.00 KB, patch)
2020-01-23 21:59 PST, Yusuke Suzuki
saam: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Yusuke Suzuki 2020-01-23 20:51:14 PST
[JSC] DFG OSR exit is not marking CodeBlock::m_hasLinkedOSRExit when the exit target is checkpoint
Comment 1 Yusuke Suzuki 2020-01-23 21:01:25 PST
Created attachment 388649 [details]
Patch
Comment 2 Yusuke Suzuki 2020-01-23 21:02:24 PST
<rdar://problem/58827849>
Comment 3 Yusuke Suzuki 2020-01-23 21:06:58 PST
Created attachment 388650 [details]
Patch
Comment 4 Mark Lam 2020-01-23 21:51:34 PST
Comment on attachment 388650 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=388650&action=review

> Source/JavaScriptCore/ChangeLog:16
> +            1. The caller CodeBlock "A" has Baseline code.
> +            2. Compile DFG code exiting to the checkpoint of "A". We are not marking "A"'s CodeBlock::m_hasLinkedOSRExit.
> +            3. GC happens and we decide dropping Baseline code for "A" since it is not marked. Switching it to LLInt.
> +            4. However, DFG OSR exit code is compiled by assuming that "A" is Baseline. So LLInt registers are not recovered correctly.
> +            5. Then, exiting to LLInt of "A", LLInt sees that LLInt registers have garbage.

Can you clarify the following:
1. GC cannot drop baseline code while the OSR exit compiler is running.  Is that true?
2. the same compiled OSR exit ramp can be used multiple times after it is compiled, and the GC can drop the baseline code between invocations of the OSR exit ramp.  Is that true?

If the OSR exit ramp is compiled to jump into the baseline code, and the baseline code has been deleted, how does the ramp adapt and exit into the LLInt instead?  I see the LLInt VM state and register being set up in the exit ramp, but I don't see how the ramp switches between jumping into the baseline code address vs the LLInt.  Am I missing something?  Thanks.
Comment 5 Saam Barati 2020-01-23 21:51:48 PST
Comment on attachment 388650 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=388650&action=review

> Source/JavaScriptCore/ChangeLog:18
> +        While marking CodeBlock::m_hasLinkedOSRExit can fix the problem, this is a tricky fix since it relies on the heuristics we introduced about throwing

I don’t see why this isn’t the entire fix. That bit isn’t a heuristic. It’s required for the correctness of throwing away baseline code. Always recovering the registers isn’t needed. I feel like we should do only what’s required.
Comment 6 Saam Barati 2020-01-23 21:52:39 PST
(In reply to Mark Lam from comment #4)
> Comment on attachment 388650 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=388650&action=review
> 
> > Source/JavaScriptCore/ChangeLog:16
> > +            1. The caller CodeBlock "A" has Baseline code.
> > +            2. Compile DFG code exiting to the checkpoint of "A". We are not marking "A"'s CodeBlock::m_hasLinkedOSRExit.
> > +            3. GC happens and we decide dropping Baseline code for "A" since it is not marked. Switching it to LLInt.
> > +            4. However, DFG OSR exit code is compiled by assuming that "A" is Baseline. So LLInt registers are not recovered correctly.
> > +            5. Then, exiting to LLInt of "A", LLInt sees that LLInt registers have garbage.
> 
> Can you clarify the following:
> 1. GC cannot drop baseline code while the OSR exit compiler is running.  Is
> that true?
> 2. the same compiled OSR exit ramp can be used multiple times after it is
> compiled, and the GC can drop the baseline code between invocations of the
> OSR exit ramp.  Is that true?
> 
> If the OSR exit ramp is compiled to jump into the baseline code, and the
> baseline code has been deleted, how does the ramp adapt and exit into the
> LLInt instead?  I see the LLInt VM state and register being set up in the
> exit ramp, but I don't see how the ramp switches between jumping into the
> baseline code address vs the LLInt.  Am I missing something?  Thanks.
 We don’t throw away baseline code once we set the “I have an OSR exit jumping to me” bit.
Comment 7 Saam Barati 2020-01-23 21:53:21 PST
Comment on attachment 388650 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=388650&action=review

> Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp:151
> +            baselineCodeBlockForCaller->m_hasLinkedOSRExit = true;

This is all that’s needed, right?
Comment 8 Yusuke Suzuki 2020-01-23 21:59:47 PST
Created attachment 388654 [details]
Patch
Comment 9 Yusuke Suzuki 2020-01-23 22:09:54 PST
Committed r255055: <https://trac.webkit.org/changeset/255055>