Title: [217221] trunk/Source/_javascript_Core
Revision
217221
Author
[email protected]
Date
2017-05-22 10:14:01 -0700 (Mon, 22 May 2017)

Log Message

FTL stack overflow handling should not assume that B3 never selects callee-saves in the prologue
https://bugs.webkit.org/show_bug.cgi?id=172455

Reviewed by Mark Lam.
        
The FTL needs to run B3's callee-save register restoration before it runs the exception
handler's callee-save register restoration.  This exposes B3's callee-save register
algorithm in AssemblyHelpers so that the FTL can call it.

* b3/air/AirGenerate.cpp:
(JSC::B3::Air::generate):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::lower): Fix the bug.
* heap/Subspace.cpp: Added some debugging support.
(JSC::Subspace::allocate):
(JSC::Subspace::tryAllocate):
(JSC::Subspace::didAllocate):
* heap/Subspace.h:
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::addressFor):
(JSC::AssemblyHelpers::emitSave):
(JSC::AssemblyHelpers::emitRestore):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (217220 => 217221)


--- trunk/Source/_javascript_Core/ChangeLog	2017-05-22 16:58:27 UTC (rev 217220)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-05-22 17:14:01 UTC (rev 217221)
@@ -1,3 +1,28 @@
+2017-05-22  Filip Pizlo  <[email protected]>
+
+        FTL stack overflow handling should not assume that B3 never selects callee-saves in the prologue
+        https://bugs.webkit.org/show_bug.cgi?id=172455
+
+        Reviewed by Mark Lam.
+        
+        The FTL needs to run B3's callee-save register restoration before it runs the exception
+        handler's callee-save register restoration.  This exposes B3's callee-save register
+        algorithm in AssemblyHelpers so that the FTL can call it.
+
+        * b3/air/AirGenerate.cpp:
+        (JSC::B3::Air::generate):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::lower): Fix the bug.
+        * heap/Subspace.cpp: Added some debugging support.
+        (JSC::Subspace::allocate):
+        (JSC::Subspace::tryAllocate):
+        (JSC::Subspace::didAllocate):
+        * heap/Subspace.h:
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::addressFor):
+        (JSC::AssemblyHelpers::emitSave):
+        (JSC::AssemblyHelpers::emitRestore):
+
 2017-05-20  Yusuke Suzuki  <[email protected]>
 
         [FTL] Support GetByVal with ArrayStorage and SlowPutArrayStorage

Modified: trunk/Source/_javascript_Core/b3/air/AirGenerate.cpp (217220 => 217221)


--- trunk/Source/_javascript_Core/b3/air/AirGenerate.cpp	2017-05-22 16:58:27 UTC (rev 217220)
+++ trunk/Source/_javascript_Core/b3/air/AirGenerate.cpp	2017-05-22 17:14:01 UTC (rev 217221)
@@ -168,10 +168,6 @@
 
     DisallowMacroScratchRegisterUsage disallowScratch(jit);
 
-    auto argFor = [&] (const RegisterAtOffset& entry) -> CCallHelpers::Address {
-        return CCallHelpers::Address(GPRInfo::callFrameRegister, entry.offset());
-    };
-    
     // And now, we generate code.
     GenerationContext context;
     context.code = &code;
@@ -222,12 +218,7 @@
                 jit.addPtr(CCallHelpers::TrustedImm32(-code.frameSize()), MacroAssembler::stackPointerRegister);
             }
             
-            for (const RegisterAtOffset& entry : code.calleeSaveRegisterAtOffsetList()) {
-                if (entry.reg().isGPR())
-                    jit.storePtr(entry.reg().gpr(), argFor(entry));
-                else
-                    jit.storeDouble(entry.reg().fpr(), argFor(entry));
-            }
+            jit.emitSave(code.calleeSaveRegisterAtOffsetList());
 
             if (disassembler)
                 disassembler->endEntrypoint(jit); 
@@ -259,12 +250,7 @@
             // have this override.
             auto start = jit.labelIgnoringWatchpoints();
             if (code.frameSize()) {
-                for (const RegisterAtOffset& entry : code.calleeSaveRegisterAtOffsetList()) {
-                    if (entry.reg().isGPR())
-                        jit.loadPtr(argFor(entry), entry.reg().gpr());
-                    else
-                        jit.loadDouble(argFor(entry), entry.reg().fpr());
-                }
+                jit.emitRestore(code.calleeSaveRegisterAtOffsetList());
                 jit.emitFunctionEpilogue();
             } else
                 jit.emitFunctionEpilogueWithEmptyFrame();

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (217220 => 217221)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2017-05-22 16:58:27 UTC (rev 217220)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2017-05-22 17:14:01 UTC (rev 217221)
@@ -226,6 +226,13 @@
                     AllowMacroScratchRegisterUsage allowScratch(jit);
 
                     stackOverflow.link(&jit);
+                    
+                    // FIXME: We would not have to do this if the stack check was part of the Air
+                    // prologue. Then, we would know that there is no way for the callee-saves to
+                    // get clobbered.
+                    // https://bugs.webkit.org/show_bug.cgi?id=172456
+                    jit.emitRestore(params.proc().calleeSaveRegisterAtOffsetList());
+                    
                     jit.store32(
                         MacroAssembler::TrustedImm32(callSiteIndex.bits()),
                         CCallHelpers::tagFor(VirtualRegister(CallFrameSlot::argumentCount)));

Modified: trunk/Source/_javascript_Core/heap/Subspace.cpp (217220 => 217221)


--- trunk/Source/_javascript_Core/heap/Subspace.cpp	2017-05-22 16:58:27 UTC (rev 217220)
+++ trunk/Source/_javascript_Core/heap/Subspace.cpp	2017-05-22 17:14:01 UTC (rev 217221)
@@ -98,6 +98,7 @@
         result = allocator->allocate();
     else
         result = allocateSlow(nullptr, size);
+    didAllocate(result);
     return result;
 }
 
@@ -108,6 +109,7 @@
         result = allocator->allocate(deferralContext);
     else
         result = allocateSlow(deferralContext, size);
+    didAllocate(result);
     return result;
 }
 
@@ -118,6 +120,7 @@
         result = allocator->tryAllocate();
     else
         result = tryAllocateSlow(nullptr, size);
+    didAllocate(result);
     return result;
 }
 
@@ -128,6 +131,7 @@
         result = allocator->tryAllocate(deferralContext);
     else
         result = tryAllocateSlow(deferralContext, size);
+    didAllocate(result);
     return result;
 }
 
@@ -204,5 +208,13 @@
     return allocation->cell();
 }
 
+ALWAYS_INLINE void Subspace::didAllocate(void* ptr)
+{
+    UNUSED_PARAM(ptr);
+    
+    // This is useful for logging allocations, or doing other kinds of debugging hacks. Just make
+    // sure you JSC_forceGCSlowPaths=true.
+}
+
 } // namespace JSC
 

Modified: trunk/Source/_javascript_Core/heap/Subspace.h (217220 => 217221)


--- trunk/Source/_javascript_Core/heap/Subspace.h	2017-05-22 16:58:27 UTC (rev 217220)
+++ trunk/Source/_javascript_Core/heap/Subspace.h	2017-05-22 17:14:01 UTC (rev 217221)
@@ -94,6 +94,8 @@
     void* allocateSlow(GCDeferralContext*, size_t);
     void* tryAllocateSlow(GCDeferralContext*, size_t);
     
+    void didAllocate(void*);
+    
     MarkedSpace& m_space;
     
     CString m_name;

Modified: trunk/Source/_javascript_Core/jit/AssemblyHelpers.h (217220 => 217221)


--- trunk/Source/_javascript_Core/jit/AssemblyHelpers.h	2017-05-22 16:58:27 UTC (rev 217220)
+++ trunk/Source/_javascript_Core/jit/AssemblyHelpers.h	2017-05-22 17:14:01 UTC (rev 217221)
@@ -229,6 +229,31 @@
         store32(TrustedImm32(value.payload()), address.withOffset(PayloadOffset));
 #endif
     }
+    
+    Address addressFor(const RegisterAtOffset& entry)
+    {
+        return Address(GPRInfo::callFrameRegister, entry.offset());
+    }
+    
+    void emitSave(const RegisterAtOffsetList& list)
+    {
+        for (const RegisterAtOffset& entry : list) {
+            if (entry.reg().isGPR())
+                storePtr(entry.reg().gpr(), addressFor(entry));
+            else
+                storeDouble(entry.reg().fpr(), addressFor(entry));
+        }
+    }
+    
+    void emitRestore(const RegisterAtOffsetList& list)
+    {
+        for (const RegisterAtOffset& entry : list) {
+            if (entry.reg().isGPR())
+                loadPtr(addressFor(entry), entry.reg().gpr());
+            else
+                loadDouble(addressFor(entry), entry.reg().fpr());
+        }
+    }
 
     void emitSaveCalleeSavesFor(CodeBlock* codeBlock)
     {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to