Title: [114675] trunk/Source/_javascript_Core
Revision
114675
Author
fpi...@apple.com
Date
2012-04-19 14:55:00 -0700 (Thu, 19 Apr 2012)

Log Message

It should be possible to perform debugCall on ARMv7
https://bugs.webkit.org/show_bug.cgi?id=84381

Reviewed by Oliver Hunt.
        
debugCall() was clobbering the argument to the call it was making, leading to a
corrupt ExecState*. This change fixes that issue by using a scratch register that
does not clobber arguments, and it also introduces more assertions that we have
a valid call frame.

* dfg/DFGAssemblyHelpers.cpp:
(DFG):
(JSC::DFG::AssemblyHelpers::jitAssertHasValidCallFrame):
* dfg/DFGAssemblyHelpers.h:
(JSC::DFG::AssemblyHelpers::selectScratchGPR):
(AssemblyHelpers):
(JSC::DFG::AssemblyHelpers::debugCall):
(JSC::DFG::AssemblyHelpers::jitAssertHasValidCallFrame):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::linkOSRExits):
* dfg/DFGOSRExitCompiler.cpp:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::selectScratchGPR):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (114674 => 114675)


--- trunk/Source/_javascript_Core/ChangeLog	2012-04-19 21:32:41 UTC (rev 114674)
+++ trunk/Source/_javascript_Core/ChangeLog	2012-04-19 21:55:00 UTC (rev 114675)
@@ -1,5 +1,33 @@
 2012-04-19  Filip Pizlo  <fpi...@apple.com>
 
+        It should be possible to perform debugCall on ARMv7
+        https://bugs.webkit.org/show_bug.cgi?id=84381
+
+        Reviewed by Oliver Hunt.
+        
+        debugCall() was clobbering the argument to the call it was making, leading to a
+        corrupt ExecState*. This change fixes that issue by using a scratch register that
+        does not clobber arguments, and it also introduces more assertions that we have
+        a valid call frame.
+
+        * dfg/DFGAssemblyHelpers.cpp:
+        (DFG):
+        (JSC::DFG::AssemblyHelpers::jitAssertHasValidCallFrame):
+        * dfg/DFGAssemblyHelpers.h:
+        (JSC::DFG::AssemblyHelpers::selectScratchGPR):
+        (AssemblyHelpers):
+        (JSC::DFG::AssemblyHelpers::debugCall):
+        (JSC::DFG::AssemblyHelpers::jitAssertHasValidCallFrame):
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::linkOSRExits):
+        * dfg/DFGOSRExitCompiler.cpp:
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::selectScratchGPR):
+
+2012-04-19  Filip Pizlo  <fpi...@apple.com>
+
         LLInt no-JIT fallback native call trampoline's exception handler incorrectly assumes that
         the PB/PC has been preserved
         https://bugs.webkit.org/show_bug.cgi?id=84367

Modified: trunk/Source/_javascript_Core/dfg/DFGAssemblyHelpers.cpp (114674 => 114675)


--- trunk/Source/_javascript_Core/dfg/DFGAssemblyHelpers.cpp	2012-04-19 21:32:41 UTC (rev 114674)
+++ trunk/Source/_javascript_Core/dfg/DFGAssemblyHelpers.cpp	2012-04-19 21:55:00 UTC (rev 114675)
@@ -140,6 +140,13 @@
     checkCell.link(this);
 }
 #endif // USE(JSVALUE32_64)
+
+void AssemblyHelpers::jitAssertHasValidCallFrame()
+{
+    Jump checkCFR = branchTestPtr(Zero, GPRInfo::callFrameRegister, TrustedImm32(7));
+    breakpoint();
+    checkCFR.link(this);
+}
 #endif // DFG_ENABLE(JIT_ASSERT)
 
 } } // namespace JSC::DFG

Modified: trunk/Source/_javascript_Core/dfg/DFGAssemblyHelpers.h (114674 => 114675)


--- trunk/Source/_javascript_Core/dfg/DFGAssemblyHelpers.h	2012-04-19 21:32:41 UTC (rev 114674)
+++ trunk/Source/_javascript_Core/dfg/DFGAssemblyHelpers.h	2012-04-19 21:55:00 UTC (rev 114675)
@@ -150,6 +150,23 @@
         return branch8(Below, Address(structureReg, Structure::typeInfoTypeOffset()), TrustedImm32(ObjectType));
     }
 
+    static GPRReg selectScratchGPR(GPRReg preserve1 = InvalidGPRReg, GPRReg preserve2 = InvalidGPRReg, GPRReg preserve3 = InvalidGPRReg, GPRReg preserve4 = InvalidGPRReg)
+    {
+        if (preserve1 != GPRInfo::regT0 && preserve2 != GPRInfo::regT0 && preserve3 != GPRInfo::regT0 && preserve4 != GPRInfo::regT0)
+            return GPRInfo::regT0;
+
+        if (preserve1 != GPRInfo::regT1 && preserve2 != GPRInfo::regT1 && preserve3 != GPRInfo::regT1 && preserve4 != GPRInfo::regT1)
+            return GPRInfo::regT1;
+
+        if (preserve1 != GPRInfo::regT2 && preserve2 != GPRInfo::regT2 && preserve3 != GPRInfo::regT2 && preserve4 != GPRInfo::regT2)
+            return GPRInfo::regT2;
+
+        if (preserve1 != GPRInfo::regT3 && preserve2 != GPRInfo::regT3 && preserve3 != GPRInfo::regT3 && preserve4 != GPRInfo::regT3)
+            return GPRInfo::regT3;
+
+        return GPRInfo::regT4;
+    }
+
     // Add a debug call. This call has no effect on JIT code execution state.
     void debugCall(V_DFGDebugOperation_EP function, void* argument)
     {
@@ -164,14 +181,16 @@
 #if CPU(X86_64) || CPU(ARM_THUMB2)
         move(TrustedImmPtr(argument), GPRInfo::argumentGPR1);
         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+        GPRReg scratch = selectScratchGPR(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1);
 #elif CPU(X86)
         poke(GPRInfo::callFrameRegister, 0);
         poke(TrustedImmPtr(argument), 1);
+        GPRReg scratch = GPRInfo::regT0;
 #else
 #error "DFG JIT not supported on this platform."
 #endif
-        move(TrustedImmPtr(reinterpret_cast<void*>(function)), GPRInfo::regT0);
-        call(GPRInfo::regT0);
+        move(TrustedImmPtr(reinterpret_cast<void*>(function)), scratch);
+        call(scratch);
         for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) {
             move(TrustedImmPtr(buffer + GPRInfo::numberOfRegisters + i), GPRInfo::regT0);
             loadDouble(GPRInfo::regT0, FPRInfo::toRegister(i));
@@ -187,12 +206,14 @@
     void jitAssertIsJSNumber(GPRReg);
     void jitAssertIsJSDouble(GPRReg);
     void jitAssertIsCell(GPRReg);
+    void jitAssertHasValidCallFrame();
 #else
     void jitAssertIsInt32(GPRReg) { }
     void jitAssertIsJSInt32(GPRReg) { }
     void jitAssertIsJSNumber(GPRReg) { }
     void jitAssertIsJSDouble(GPRReg) { }
     void jitAssertIsCell(GPRReg) { }
+    void jitAssertHasValidCallFrame() { }
 #endif
 
     // These methods convert between doubles, and doubles boxed and JSValues.

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp (114674 => 114675)


--- trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp	2012-04-19 21:32:41 UTC (rev 114674)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp	2012-04-19 21:55:00 UTC (rev 114675)
@@ -44,6 +44,7 @@
     for (unsigned i = 0; i < codeBlock()->numberOfOSRExits(); ++i) {
         OSRExit& exit = codeBlock()->osrExit(i);
         exit.m_check.initialJump().link(this);
+        jitAssertHasValidCallFrame();
         store32(TrustedImm32(i), &globalData()->osrExitIndex);
         beginUninterruptedSequence();
         exit.m_check.switchToLateJump(jump());

Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler.cpp (114674 => 114675)


--- trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler.cpp	2012-04-19 21:32:41 UTC (rev 114674)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler.cpp	2012-04-19 21:55:00 UTC (rev 114675)
@@ -74,7 +74,8 @@
     {
         AssemblyHelpers jit(globalData, codeBlock);
         OSRExitCompiler exitCompiler(jit);
-        
+
+        jit.jitAssertHasValidCallFrame();
         exitCompiler.compileExit(exit, recovery);
         
         LinkBuffer patchBuffer(*globalData, &jit, codeBlock);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (114674 => 114675)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2012-04-19 21:32:41 UTC (rev 114674)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2012-04-19 21:55:00 UTC (rev 114675)
@@ -931,6 +931,8 @@
 #if DFG_ENABLE(JIT_BREAK_ON_EVERY_BLOCK)
     m_jit.breakpoint();
 #endif
+    
+    m_jit.jitAssertHasValidCallFrame();
 
     ASSERT(m_arguments.size() == block.variablesAtHead.numberOfArguments());
     for (size_t i = 0; i < m_arguments.size(); ++i) {

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (114674 => 114675)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2012-04-19 21:32:41 UTC (rev 114674)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2012-04-19 21:55:00 UTC (rev 114675)
@@ -342,19 +342,7 @@
 
     static GPRReg selectScratchGPR(GPRReg preserve1 = InvalidGPRReg, GPRReg preserve2 = InvalidGPRReg, GPRReg preserve3 = InvalidGPRReg, GPRReg preserve4 = InvalidGPRReg)
     {
-        if (preserve1 != GPRInfo::regT0 && preserve2 != GPRInfo::regT0 && preserve3 != GPRInfo::regT0 && preserve4 != GPRInfo::regT0)
-            return GPRInfo::regT0;
-
-        if (preserve1 != GPRInfo::regT1 && preserve2 != GPRInfo::regT1 && preserve3 != GPRInfo::regT1 && preserve4 != GPRInfo::regT1)
-            return GPRInfo::regT1;
-
-        if (preserve1 != GPRInfo::regT2 && preserve2 != GPRInfo::regT2 && preserve3 != GPRInfo::regT2 && preserve4 != GPRInfo::regT2)
-            return GPRInfo::regT2;
-
-        if (preserve1 != GPRInfo::regT3 && preserve2 != GPRInfo::regT3 && preserve3 != GPRInfo::regT3 && preserve4 != GPRInfo::regT3)
-            return GPRInfo::regT3;
-
-        return GPRInfo::regT4;
+        return AssemblyHelpers::selectScratchGPR(preserve1, preserve2, preserve3, preserve4);
     }
 
     // Called by the speculative operand types, below, to fill operand to
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to