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);