Title: [195707] trunk/Source/_javascript_Core
Revision
195707
Author
[email protected]
Date
2016-01-27 16:29:09 -0800 (Wed, 27 Jan 2016)

Log Message

[JSC] adjustFrameAndStackInOSRExitCompilerThunk() can trash values in FTL
https://bugs.webkit.org/show_bug.cgi?id=153536

Patch by Benjamin Poulain <[email protected]> on 2016-01-27
Reviewed by Saam Barati.

Workaround to get B3 working on ARM.

* dfg/DFGOSRExitCompilerCommon.h:
(JSC::DFG::adjustFrameAndStackInOSRExitCompilerThunk):
The code was using the scratch registers in a few places.

I initially tried to make is not use scratch registers anywhere
but that looked super fragile.

Instead, I just preserve the scratch registers. That's easy and
it should be relatively cheap compared to everything done on OSR Exits.

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (195706 => 195707)


--- trunk/Source/_javascript_Core/ChangeLog	2016-01-28 00:18:37 UTC (rev 195706)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-01-28 00:29:09 UTC (rev 195707)
@@ -1,3 +1,22 @@
+2016-01-27  Benjamin Poulain  <[email protected]>
+
+        [JSC] adjustFrameAndStackInOSRExitCompilerThunk() can trash values in FTL
+        https://bugs.webkit.org/show_bug.cgi?id=153536
+
+        Reviewed by Saam Barati.
+
+        Workaround to get B3 working on ARM.
+
+        * dfg/DFGOSRExitCompilerCommon.h:
+        (JSC::DFG::adjustFrameAndStackInOSRExitCompilerThunk):
+        The code was using the scratch registers in a few places.
+
+        I initially tried to make is not use scratch registers anywhere
+        but that looked super fragile.
+
+        Instead, I just preserve the scratch registers. That's easy and
+        it should be relatively cheap compared to everything done on OSR Exits.
+
 2016-01-27  Konstantin Tokarev  <[email protected]>
 
         [mips] Use reinterpret_cast_ptr to suppress alignment warnings.

Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExitCompilerCommon.h (195706 => 195707)


--- trunk/Source/_javascript_Core/dfg/DFGOSRExitCompilerCommon.h	2016-01-28 00:18:37 UTC (rev 195706)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExitCompilerCommon.h	2016-01-28 00:29:09 UTC (rev 195707)
@@ -33,6 +33,7 @@
 #include "DFGCommonData.h"
 #include "DFGJITCode.h"
 #include "FTLJITCode.h"
+#include "RegisterSet.h"
 
 namespace JSC { namespace DFG {
 
@@ -44,22 +45,40 @@
 void adjustFrameAndStackInOSRExitCompilerThunk(MacroAssembler& jit, VM* vm, JITCode::JITType jitType)
 {
     ASSERT(jitType == JITCode::DFGJIT || jitType == JITCode::FTLJIT);
-    size_t scratchSize = sizeof(void*);
+
     bool isFTLOSRExit = jitType == JITCode::FTLJIT;
+    RegisterSet registersToPreserve;
+    registersToPreserve.set(GPRInfo::regT0);
+    if (isFTLOSRExit) {
+        // FTL can use the scratch registers for values. The code below uses
+        // the scratch registers. We need to preserve them before doing anything.
+        registersToPreserve.merge(RegisterSet::macroScratchRegisters());
+    }
+
+    size_t scratchSize = sizeof(void*) * registersToPreserve.numberOfSetGPRs();
     if (isFTLOSRExit)
         scratchSize += sizeof(void*);
 
     ScratchBuffer* scratchBuffer = vm->scratchBufferForSize(scratchSize);
     char* buffer = static_cast<char*>(scratchBuffer->dataBuffer());
-    jit.storePtr(GPRInfo::regT0, buffer);
 
+    jit.pushToSave(GPRInfo::regT1);
+    jit.move(MacroAssembler::TrustedImmPtr(buffer), GPRInfo::regT1);
+
+    unsigned storeOffset = 0;
+    registersToPreserve.forEach([&](Reg reg) {
+        jit.storePtr(reg.gpr(), MacroAssembler::Address(GPRInfo::regT1, storeOffset));
+        storeOffset += sizeof(void*);
+    });
+
     if (isFTLOSRExit) {
         // FTL OSRExits are entered via the code FTLExitThunkGenerator emits which does
         // pushToSaveImmediateWithoutTouchRegisters with the OSR exit index. We need to load
         // that top value and then push it back when we reset our SP.
-        jit.peek(GPRInfo::regT0);
-        jit.storePtr(GPRInfo::regT0, buffer + sizeof(void*));
+        jit.loadPtr(MacroAssembler::Address(MacroAssembler::stackPointerRegister, MacroAssembler::pushToSaveByteOffset()), GPRInfo::regT0);
+        jit.storePtr(GPRInfo::regT0, MacroAssembler::Address(GPRInfo::regT1, registersToPreserve.numberOfSetGPRs() * sizeof(void*)));
     }
+    jit.popToRestore(GPRInfo::regT1);
 
     // We need to reset FP in the case of an exception.
     jit.loadPtr(vm->addressOfCallFrameForCatch(), GPRInfo::regT0);
@@ -85,14 +104,26 @@
     jit.move(GPRInfo::regT0, MacroAssembler::stackPointerRegister);
 
     if (isFTLOSRExit) {
+        // Leave space for saving the OSR Exit Index.
+        jit.subPtr(MacroAssembler::TrustedImm32(MacroAssembler::pushToSaveByteOffset()), MacroAssembler::stackPointerRegister);
+    }
+    jit.pushToSave(GPRInfo::regT1);
+
+    jit.move(MacroAssembler::TrustedImmPtr(buffer), GPRInfo::regT1);
+    if (isFTLOSRExit) {
         // FTL OSRExits are entered via FTLExitThunkGenerator code with does
         // pushToSaveImmediateWithoutTouchRegisters. We need to load that top
         // register and then store it back when we have our SP back to a safe value.
-        jit.loadPtr(buffer + sizeof(void*), GPRInfo::regT0);
-        jit.pushToSave(GPRInfo::regT0);
+        jit.loadPtr(MacroAssembler::Address(GPRInfo::regT1, registersToPreserve.numberOfSetGPRs() * sizeof(void*)), GPRInfo::regT0);
+        jit.storePtr(GPRInfo::regT0, MacroAssembler::Address(MacroAssembler::stackPointerRegister, MacroAssembler::pushToSaveByteOffset()));
     }
 
-    jit.loadPtr(buffer, GPRInfo::regT0);
+    unsigned loadOffset = 0;
+    registersToPreserve.forEach([&](Reg reg) {
+        jit.loadPtr(MacroAssembler::Address(GPRInfo::regT1, loadOffset), reg.gpr());
+        loadOffset += sizeof(void*);
+    });
+    jit.popToRestore(GPRInfo::regT1);
 }
 
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to