Bug 181570 - REGRESSION(226788): AppStore Crashed @ JavaScriptCore: JSC::MacroAssemblerARM64::pushToSaveImmediateWithoutTouchingRegisters
Summary: REGRESSION(226788): AppStore Crashed @ JavaScriptCore: JSC::MacroAssemblerARM...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: Other
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Michael Saboff
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2018-01-11 18:33 PST by Michael Saboff
Modified: 2018-01-17 18:05 PST (History)
6 users (show)

See Also:


Attachments
Patch (2.47 KB, patch)
2018-01-11 18:38 PST, Michael Saboff
keith_miller: review-
Details | Formatted Diff | Diff
Updated Patch (2.52 KB, patch)
2018-01-11 19:02 PST, Michael Saboff
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Michael Saboff 2018-01-11 18:33:52 PST
Backtrace

- Crashing App -
AppStore

- Crash Information -
Exception Type:  EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x0000000102388d90
Termination Signal: Trace/BPT trap: 5
Termination Reason: Namespace SIGNAL, Code 0x5
Terminating Process: exc handler [0]
Triggered by Thread:  24

Backtrace:
Thread 24 name:  WTF::AutomaticThread
Thread 24 Crashed:
0   JavaScriptCore                	0x0000000102388d90 JSC::MacroAssemblerARM64::pushToSaveImmediateWithoutTouchingRegisters(JSC::AbstractMacroAssembler<JSC::ARM64Assembler>::TrustedImm32) + 200
1   JavaScriptCore                	0x0000000102386ab0 JSC::FTL::OSRExitHandle::emitExitThunk(JSC::FTL::State&, JSC::CCallHelpers&) + 88


The change in change set r226788, changed pushToSaveImmediateWithoutTouchingRegisters() to use getCachedDataTempRegisterIDAndInvalidate() instead of dataTempRegister.  That doesn't work here in the FTL code because there aren't any cached registers and so we hit the RELEASE_ASSERT() at the top of getCachedDataTempRegisterIDAndInvalidate().  Reverting pushToSaveImmediateWithoutTouchingRegisters() to use dataTempRegister with a comment why it has to be that way.
Comment 1 Michael Saboff 2018-01-11 18:34:08 PST
<rdar://problem/36451128>
Comment 2 Michael Saboff 2018-01-11 18:38:29 PST
Created attachment 331153 [details]
Patch
Comment 3 Saam Barati 2018-01-11 18:43:17 PST
Comment on attachment 331153 [details]
Patch

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

> Source/JavaScriptCore/assembler/MacroAssemblerARM64.h:2208
> +        // We must use dataTempRegister directly here, because this is called from the FTL exit code
> +        // where we don't have scratch registers (m_allowScratchRegister is false)
> +        RegisterID reg = dataTempRegister;

How does this solve our problem? Isn't that saying it's invalid to use this?
Comment 4 Keith Miller 2018-01-11 18:44:42 PST
Comment on attachment 331153 [details]
Patch

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

> Source/JavaScriptCore/ChangeLog:10
> +        Reverting these functions to use dataTempRegister and memoryTempRegister as they may
> +        be called from code that doesn't use cached registers.  Added comments in each case
> +        why this is safe.

It seems like the actual fix is to make the callers of those functions set m_allowScratchRegister = true.
Comment 5 Michael Saboff 2018-01-11 18:48:03 PST
(In reply to Saam Barati from comment #3)
> Comment on attachment 331153 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=331153&action=review
> 
> > Source/JavaScriptCore/assembler/MacroAssemblerARM64.h:2208
> > +        // We must use dataTempRegister directly here, because this is called from the FTL exit code
> > +        // where we don't have scratch registers (m_allowScratchRegister is false)
> > +        RegisterID reg = dataTempRegister;
> 
> How does this solve our problem? Isn't that saying it's invalid to use this?

That flag says that scratch registers are cached and need to be managed.  It is set false when the calling code is managing registers itself.
Comment 6 Michael Saboff 2018-01-11 18:49:14 PST
(In reply to Keith Miller from comment #4)
> Comment on attachment 331153 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=331153&action=review
> 
> > Source/JavaScriptCore/ChangeLog:10
> > +        Reverting these functions to use dataTempRegister and memoryTempRegister as they may
> > +        be called from code that doesn't use cached registers.  Added comments in each case
> > +        why this is safe.
> 
> It seems like the actual fix is to make the callers of those functions set
> m_allowScratchRegister = true.

If we do that, then we run the risk that a register gets cached and later possible trashed.
Comment 7 Michael Saboff 2018-01-11 19:02:14 PST
Created attachment 331156 [details]
Updated Patch
Comment 8 Keith Miller 2018-01-11 19:03:16 PST
Comment on attachment 331156 [details]
Updated Patch

r=me.
Comment 9 Saam Barati 2018-01-11 19:23:42 PST
Comment on attachment 331156 [details]
Updated Patch

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

> Source/JavaScriptCore/assembler/MacroAssemblerARM64.h:2207
> +        RegisterID reg = m_allowScratchRegister ? getCachedDataTempRegisterIDAndInvalidate() : dataTempRegister;

Why is this correct? Isn’t the assert telling us it’s not safe to use that register? E.g, we’re trashing  it here? 

This code looks footgun-y. If it’s indeed safe to do this in the FTL, why don’t you wrap calls to this with AllowMacroScratchUsage
Comment 10 WebKit Commit Bot 2018-01-11 19:30:45 PST
Comment on attachment 331156 [details]
Updated Patch

Clearing flags on attachment: 331156

Committed r226840: <https://trac.webkit.org/changeset/226840>
Comment 11 WebKit Commit Bot 2018-01-11 19:30:46 PST
All reviewed patches have been landed.  Closing bug.
Comment 12 Michael Saboff 2018-01-11 20:26:46 PST
(In reply to Saam Barati from comment #9)
> Comment on attachment 331156 [details]
> Updated Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=331156&action=review
> 
> > Source/JavaScriptCore/assembler/MacroAssemblerARM64.h:2207
> > +        RegisterID reg = m_allowScratchRegister ? getCachedDataTempRegisterIDAndInvalidate() : dataTempRegister;
> 
> Why is this correct? Isn’t the assert telling us it’s not safe to use that
> register? E.g, we’re trashing  it here? 
> 
> This code looks footgun-y. If it’s indeed safe to do this in the FTL, why
> don’t you wrap calls to this with AllowMacroScratchUsage

We don't want to change that we allow scratch registers, we want to handle both cases.
Comment 13 Saam Barati 2018-01-11 21:08:01 PST
(In reply to Michael Saboff from comment #12)
> (In reply to Saam Barati from comment #9)
> > Comment on attachment 331156 [details]
> > Updated Patch
> > 
> > View in context:
> > https://bugs.webkit.org/attachment.cgi?id=331156&action=review
> > 
> > > Source/JavaScriptCore/assembler/MacroAssemblerARM64.h:2207
> > > +        RegisterID reg = m_allowScratchRegister ? getCachedDataTempRegisterIDAndInvalidate() : dataTempRegister;
> > 
> > Why is this correct? Isn’t the assert telling us it’s not safe to use that
> > register? E.g, we’re trashing  it here? 
> > 
> > This code looks footgun-y. If it’s indeed safe to do this in the FTL, why
> > don’t you wrap calls to this with AllowMacroScratchUsage
> 
> We don't want to change that we allow scratch registers, we want to handle
> both cases.

But you're unconditionally using the scratch. Am I missing something?
Comment 14 Saam Barati 2018-01-17 18:05:36 PST
Comment on attachment 331156 [details]
Updated Patch

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

>>>> Source/JavaScriptCore/assembler/MacroAssemblerARM64.h:2207
>>>> +        RegisterID reg = m_allowScratchRegister ? getCachedDataTempRegisterIDAndInvalidate() : dataTempRegister;
>>> 
>>> Why is this correct? Isn’t the assert telling us it’s not safe to use that register? E.g, we’re trashing  it here? 
>>> 
>>> This code looks footgun-y. If it’s indeed safe to do this in the FTL, why don’t you wrap calls to this with AllowMacroScratchUsage
>> 
>> We don't want to change that we allow scratch registers, we want to handle both cases.
> 
> But you're unconditionally using the scratch. Am I missing something?

I lost important context on what this function is doing. It always recovers the value that was in dataTempRegister. Therefore, it should never invalidate it what's in dataTempRegister, since whatever is in there will be recovered.