Save and restore callee save registers in WebAssembly
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 17 Sep 2015 17:38:08 +0000 (17:38 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 17 Sep 2015 17:38:08 +0000 (17:38 +0000)
https://bugs.webkit.org/show_bug.cgi?id=149247

Patch by Sukolsak Sakshuwong <sukolsak@gmail.com> on 2015-09-17
Reviewed by Michael Saboff.

Save callee save registers when entering WebAssembly functions
and restore them when returning.

* jit/RegisterSet.cpp:
(JSC::RegisterSet::webAssemblyCalleeSaveRegisters):
* jit/RegisterSet.h:
* wasm/WASMFunctionCompiler.h:
(JSC::WASMFunctionCompiler::startFunction):
(JSC::WASMFunctionCompiler::endFunction):
(JSC::WASMFunctionCompiler::buildReturn):
(JSC::WASMFunctionCompiler::localAddress):
(JSC::WASMFunctionCompiler::temporaryAddress):
(JSC::WASMFunctionCompiler::boxArgumentsAndAdjustStackPointer):
(JSC::WASMFunctionCompiler::callAndUnboxResult):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@189917 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/jit/RegisterSet.cpp
Source/JavaScriptCore/jit/RegisterSet.h
Source/JavaScriptCore/wasm/WASMFunctionCompiler.h

index 8ffb49c..b2a5dd4 100644 (file)
@@ -1,3 +1,25 @@
+2015-09-17  Sukolsak Sakshuwong  <sukolsak@gmail.com>
+
+        Save and restore callee save registers in WebAssembly
+        https://bugs.webkit.org/show_bug.cgi?id=149247
+
+        Reviewed by Michael Saboff.
+
+        Save callee save registers when entering WebAssembly functions
+        and restore them when returning.
+
+        * jit/RegisterSet.cpp:
+        (JSC::RegisterSet::webAssemblyCalleeSaveRegisters):
+        * jit/RegisterSet.h:
+        * wasm/WASMFunctionCompiler.h:
+        (JSC::WASMFunctionCompiler::startFunction):
+        (JSC::WASMFunctionCompiler::endFunction):
+        (JSC::WASMFunctionCompiler::buildReturn):
+        (JSC::WASMFunctionCompiler::localAddress):
+        (JSC::WASMFunctionCompiler::temporaryAddress):
+        (JSC::WASMFunctionCompiler::boxArgumentsAndAdjustStackPointer):
+        (JSC::WASMFunctionCompiler::callAndUnboxResult):
+
 2015-09-16  Sukolsak Sakshuwong  <sukolsak@gmail.com>
 
         Implement indirect calls in WebAssembly
index a0d0dbe..be4c68b 100644 (file)
@@ -274,6 +274,39 @@ RegisterSet RegisterSet::ftlCalleeSaveRegisters()
     return result;
 }
 
+#if ENABLE(WEBASSEMBLY)
+RegisterSet RegisterSet::webAssemblyCalleeSaveRegisters()
+{
+    RegisterSet result;
+#if CPU(X86)
+#elif CPU(X86_64)
+#if !OS(WINDOWS)
+    ASSERT(GPRInfo::regCS3 == GPRInfo::tagTypeNumberRegister);
+    ASSERT(GPRInfo::regCS4 == GPRInfo::tagMaskRegister);
+    result.set(GPRInfo::regCS3);
+    result.set(GPRInfo::regCS4);
+#else
+    ASSERT(GPRInfo::regCS5 == GPRInfo::tagTypeNumberRegister);
+    ASSERT(GPRInfo::regCS6 == GPRInfo::tagMaskRegister);
+    result.set(GPRInfo::regCS5);
+    result.set(GPRInfo::regCS6);
+#endif
+#elif CPU(ARM_THUMB2)
+#elif CPU(ARM_TRADITIONAL)
+#elif CPU(ARM64)
+    ASSERT(GPRInfo::regCS8 == GPRInfo::tagTypeNumberRegister);
+    ASSERT(GPRInfo::regCS9 == GPRInfo::tagMaskRegister);
+    result.set(GPRInfo::regCS8);
+    result.set(GPRInfo::regCS9);
+#elif CPU(MIPS)
+#elif CPU(SH4)
+#else
+    UNREACHABLE_FOR_PLATFORM();
+#endif
+    return result;
+}
+#endif
+
 RegisterSet RegisterSet::allGPRs()
 {
     RegisterSet result;
index 36630d1..9f5cd5e 100644 (file)
@@ -54,6 +54,9 @@ public:
     static RegisterSet llintBaselineCalleeSaveRegisters(); // Registers saved and used by the LLInt.
     static RegisterSet dfgCalleeSaveRegisters(); // Registers saved and used by the DFG JIT.
     static RegisterSet ftlCalleeSaveRegisters(); // Registers that might be saved and used by the FTL JIT.
+#if ENABLE(WEBASSEMBLY)
+    static RegisterSet webAssemblyCalleeSaveRegisters(); // Registers saved and used by the WebAssembly JIT.
+#endif
     static RegisterSet stubUnavailableRegisters(); // The union of callee saves and special registers.
     static RegisterSet allGPRs();
     static RegisterSet allFPRs();
index 35dee74..a0c27b8 100644 (file)
@@ -91,17 +91,23 @@ public:
 
     void startFunction(const Vector<WASMType>& arguments, uint32_t numberOfI32LocalVariables, uint32_t numberOfF32LocalVariables, uint32_t numberOfF64LocalVariables)
     {
+        m_calleeSaveSpace = WTF::roundUpToMultipleOf(sizeof(StackSlot), RegisterSet::webAssemblyCalleeSaveRegisters().numberOfSetRegisters() * sizeof(void*));
+        m_codeBlock->setCalleeSaveRegisters(RegisterSet::webAssemblyCalleeSaveRegisters());
+
         emitFunctionPrologue();
         emitPutImmediateToCallFrameHeader(m_codeBlock, JSStack::CodeBlock);
 
         m_beginLabel = label();
 
-        addPtr(TrustedImm32(-WTF::roundUpToMultipleOf(stackAlignmentRegisters(), m_stackHeight) * sizeof(StackSlot) - maxFrameExtentForSlowPathCall), GPRInfo::callFrameRegister, GPRInfo::regT1);
+        addPtr(TrustedImm32(-m_calleeSaveSpace - WTF::roundUpToMultipleOf(stackAlignmentRegisters(), m_stackHeight) * sizeof(StackSlot) - maxFrameExtentForSlowPathCall), GPRInfo::callFrameRegister, GPRInfo::regT1);
         m_stackOverflow = branchPtr(Above, AbsoluteAddress(m_vm->addressOfStackLimit()), GPRInfo::regT1);
 
         move(GPRInfo::regT1, stackPointerRegister);
         checkStackPointerAlignment();
 
+        emitSaveCalleeSaves();
+        emitMaterializeTagCheckRegisters();
+
         m_numberOfLocals = arguments.size() + numberOfI32LocalVariables + numberOfF32LocalVariables + numberOfF64LocalVariables;
 
         unsigned localIndex = 0;
@@ -159,6 +165,7 @@ public:
         JSValueRegs returnValueRegs(GPRInfo::returnValueGPR2, GPRInfo::returnValueGPR);
 #endif
         moveTrustedValue(jsUndefined(), returnValueRegs);
+        emitRestoreCalleeSaves();
         emitFunctionEpilogue();
         ret();
 
@@ -184,6 +191,8 @@ public:
         if (!m_exceptionChecks.empty()) {
             m_exceptionChecks.link(this);
 
+            copyCalleeSavesToVMCalleeSavesBuffer();
+
             // lookupExceptionHandler is passed two arguments, the VM and the exec (the CallFrame*).
             move(TrustedImmPtr(vm()), GPRInfo::argumentGPR0);
             move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
@@ -289,6 +298,7 @@ public:
         default:
             ASSERT_NOT_REACHED();
         }
+        emitRestoreCalleeSaves();
         emitFunctionEpilogue();
         ret();
     }
@@ -804,13 +814,13 @@ private:
     Address localAddress(unsigned localIndex) const
     {
         ASSERT(localIndex < m_numberOfLocals);
-        return Address(GPRInfo::callFrameRegister, -(localIndex + 1) * sizeof(StackSlot));
+        return Address(GPRInfo::callFrameRegister, -m_calleeSaveSpace - (localIndex + 1) * sizeof(StackSlot));
     }
 
     Address temporaryAddress(unsigned temporaryIndex) const
     {
         ASSERT(m_numberOfLocals + temporaryIndex < m_stackHeight);
-        return Address(GPRInfo::callFrameRegister, -(m_numberOfLocals + temporaryIndex + 1) * sizeof(StackSlot));
+        return Address(GPRInfo::callFrameRegister, -m_calleeSaveSpace - (m_numberOfLocals + temporaryIndex + 1) * sizeof(StackSlot));
     }
 
     void appendCall(const FunctionPtr& function)
@@ -913,7 +923,7 @@ private:
     void boxArgumentsAndAdjustStackPointer(const Vector<WASMType>& arguments)
     {
         size_t argumentCount = arguments.size();
-        int stackOffset = -WTF::roundUpToMultipleOf(stackAlignmentRegisters(), m_numberOfLocals + m_tempStackTop + argumentCount + 1 + JSStack::CallFrameHeaderSize);
+        int stackOffset = -m_calleeSaveSpace - WTF::roundUpToMultipleOf(stackAlignmentRegisters(), m_numberOfLocals + m_tempStackTop + argumentCount + 1 + JSStack::CallFrameHeaderSize);
 
         storeTrustedValue(jsUndefined(), Address(GPRInfo::callFrameRegister, (stackOffset + CallFrame::thisArgumentOffset()) * sizeof(Register)));
 
@@ -966,7 +976,7 @@ private:
         m_callCompilationInfo.last().callReturnLocation = emitNakedCall(m_vm->getCTIStub(linkCallThunkGenerator).code());
 
         end.link(this);
-        addPtr(TrustedImm32(-WTF::roundUpToMultipleOf(stackAlignmentRegisters(), m_stackHeight) * sizeof(StackSlot) - maxFrameExtentForSlowPathCall), GPRInfo::callFrameRegister, stackPointerRegister);
+        addPtr(TrustedImm32(-m_calleeSaveSpace - WTF::roundUpToMultipleOf(stackAlignmentRegisters(), m_stackHeight) * sizeof(StackSlot) - maxFrameExtentForSlowPathCall), GPRInfo::callFrameRegister, stackPointerRegister);
         checkStackPointerAlignment();
 
         switch (returnType) {
@@ -1048,6 +1058,7 @@ private:
     unsigned m_stackHeight;
     unsigned m_numberOfLocals;
     unsigned m_tempStackTop { 0 };
+    unsigned m_calleeSaveSpace;
 
     Vector<JumpTarget> m_breakTargets;
     Vector<JumpTarget> m_continueTargets;