Fix handling of indirect stackmap locations in FTL OSR exit
https://bugs.webkit.org/show_bug.cgi?id=122666

Reviewed by Mark Hahnenberg.
        
With this change, the llvm.webkit.stackmap-based OSR exit only fails one test, down from
five tests previously.

* ftl/FTLLocation.cpp:
(JSC::FTL::Location::gpr): It's OK to call this method when kind() == Indirect, so asserting that isGPR() is wrong; change to assert that involvesGPR().
(JSC::FTL::Location::restoreInto): Stack-related registers aren't saved to the scratch buffer, so use them directly.
* ftl/FTLLocation.h: Add comment about requirements for stack layout.
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileStubWithOSRExitStackmap): Make enough room on the stack so that saveAllRegisters() has a scratchpad to save things to. Without this, saveAllRegisters() may clobber a spilled value.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@157326 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp b/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp
index c596832..a3a7c3b 100644
--- a/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp
+++ b/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp
@@ -67,10 +67,17 @@
     EncodedJSValue* scratch = scratchBuffer ? static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) : 0;
     char* registerScratch = bitwise_cast<char*>(scratch + exit.m_values.size());
     
+    // Make sure that saveAllRegisters() has a place on top of the stack to spill things. That
+    // function expects to be able to use top of stack for scratch memory.
+    jit.push(GPRInfo::regT0);
     saveAllRegisters(jit, registerScratch);
     
     // Bring the stack back into a sane form.
     jit.pop(GPRInfo::regT0);
+    jit.pop(GPRInfo::regT0);
+    
+    // The remaining code assumes that SP/FP are in the same state that they were in the FTL's
+    // call frame.
     
     // Get the call frame and tag thingies.
     record->locations[0].restoreInto(jit, jitCode->stackmaps, registerScratch, GPRInfo::callFrameRegister);