Title: [166666] trunk/Source/WebCore
Revision
166666
Author
[email protected]
Date
2014-04-02 14:27:31 -0700 (Wed, 02 Apr 2014)

Log Message

Refactor the function call generator to take the arguments by value
https://bugs.webkit.org/show_bug.cgi?id=131129

Reviewed by Andreas Kling.

Nothing forces the pointed address to stay alive between setOneArgument/setTwoArguments
and prepareAndCall.

This patch changes FunctionCall to:
-Keep the register by value instead of using pointers.
-Crash at compile time if a register is invalid.

* cssjit/FunctionCall.h:
(WebCore::FunctionCall::FunctionCall):
(WebCore::FunctionCall::setOneArgument):
(WebCore::FunctionCall::setTwoArguments):
(WebCore::FunctionCall::swapArguments):
(WebCore::FunctionCall::prepareAndCall):
* cssjit/RegisterAllocator.h:
(WebCore::RegisterAllocator::isValidRegister):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (166665 => 166666)


--- trunk/Source/WebCore/ChangeLog	2014-04-02 21:06:33 UTC (rev 166665)
+++ trunk/Source/WebCore/ChangeLog	2014-04-02 21:27:31 UTC (rev 166666)
@@ -1,3 +1,26 @@
+2014-04-02  Benjamin Poulain  <[email protected]>
+
+        Refactor the function call generator to take the arguments by value
+        https://bugs.webkit.org/show_bug.cgi?id=131129
+
+        Reviewed by Andreas Kling.
+
+        Nothing forces the pointed address to stay alive between setOneArgument/setTwoArguments
+        and prepareAndCall.
+
+        This patch changes FunctionCall to:
+        -Keep the register by value instead of using pointers.
+        -Crash at compile time if a register is invalid.
+
+        * cssjit/FunctionCall.h:
+        (WebCore::FunctionCall::FunctionCall):
+        (WebCore::FunctionCall::setOneArgument):
+        (WebCore::FunctionCall::setTwoArguments):
+        (WebCore::FunctionCall::swapArguments):
+        (WebCore::FunctionCall::prepareAndCall):
+        * cssjit/RegisterAllocator.h:
+        (WebCore::RegisterAllocator::isValidRegister):
+
 2014-04-02  Daniel Bates  <[email protected]>
 
         Remove Settings::maximumDecodedImageSize()

Modified: trunk/Source/WebCore/cssjit/FunctionCall.h (166665 => 166666)


--- trunk/Source/WebCore/cssjit/FunctionCall.h	2014-04-02 21:06:33 UTC (rev 166665)
+++ trunk/Source/WebCore/cssjit/FunctionCall.h	2014-04-02 21:27:31 UTC (rev 166666)
@@ -42,8 +42,9 @@
         , m_registerAllocator(registerAllocator)
         , m_stackAllocator(stackAllocator)
         , m_callRegistry(callRegistry)
-        , m_firstArgument(nullptr)
-        , m_secondArgument(nullptr)
+        , m_argumentCount(0)
+        , m_firstArgument(InvalidGPRReg)
+        , m_secondArgument(InvalidGPRReg)
     {
     }
 
@@ -54,13 +55,15 @@
 
     void setOneArgument(const JSC::MacroAssembler::RegisterID& registerID)
     {
-        m_firstArgument = &registerID;
+        m_argumentCount = 1;
+        m_firstArgument = registerID;
     }
 
     void setTwoArguments(const JSC::MacroAssembler::RegisterID& firstRegisterID, const JSC::MacroAssembler::RegisterID& secondRegisterID)
     {
-        m_firstArgument = &firstRegisterID;
-        m_secondArgument = &secondRegisterID;
+        m_argumentCount = 2;
+        m_firstArgument = firstRegisterID;
+        m_secondArgument = secondRegisterID;
     }
 
     void call()
@@ -80,8 +83,8 @@
 private:
     void swapArguments()
     {
-        JSC::MacroAssembler::RegisterID a = *m_firstArgument;
-        JSC::MacroAssembler::RegisterID b = *m_secondArgument;
+        JSC::MacroAssembler::RegisterID a = m_firstArgument;
+        JSC::MacroAssembler::RegisterID b = m_secondArgument;
         // x86 can swap without a temporary register. On other architectures, we need allocate a temporary register to switch the values.
 #if CPU(X86) || CPU(X86_64)
         m_assembler.swap(a, b);
@@ -117,31 +120,37 @@
         saveAllocatedRegisters();
         m_stackAllocator.alignStackPreFunctionCall();
 
-        if (m_secondArgument) {
-            if (*m_firstArgument != JSC::GPRInfo::argumentGPR0) {
+        if (m_argumentCount == 2) {
+            RELEASE_ASSERT(RegisterAllocator::isValidRegister(m_firstArgument));
+            RELEASE_ASSERT(RegisterAllocator::isValidRegister(m_secondArgument));
+
+            if (m_firstArgument != JSC::GPRInfo::argumentGPR0) {
                 // If firstArgument is not in argumentGPR0, we need to handle potential conflicts:
                 // -if secondArgument and firstArgument are in inversted registers, just swap the values.
                 // -if secondArgument is in argumentGPR0 but firstArgument is not taking argumentGPR1, we can move in order secondArgument->argumentGPR1, firstArgument->argumentGPR0
                 // -if secondArgument does not take argumentGPR0, firstArgument and secondArgument can be moved safely to destination.
-                if (*m_secondArgument == JSC::GPRInfo::argumentGPR0) {
-                    if (*m_firstArgument == JSC::GPRInfo::argumentGPR1)
+                if (m_secondArgument == JSC::GPRInfo::argumentGPR0) {
+                    if (m_firstArgument == JSC::GPRInfo::argumentGPR1)
                         swapArguments();
                     else {
                         m_assembler.move(JSC::GPRInfo::argumentGPR0, JSC::GPRInfo::argumentGPR1);
-                        m_assembler.move(*m_firstArgument, JSC::GPRInfo::argumentGPR0);
+                        m_assembler.move(m_firstArgument, JSC::GPRInfo::argumentGPR0);
                     }
                 } else {
-                    m_assembler.move(*m_firstArgument, JSC::GPRInfo::argumentGPR0);
-                    if (*m_secondArgument != JSC::GPRInfo::argumentGPR1)
-                        m_assembler.move(*m_secondArgument, JSC::GPRInfo::argumentGPR1);
+                    m_assembler.move(m_firstArgument, JSC::GPRInfo::argumentGPR0);
+                    if (m_secondArgument != JSC::GPRInfo::argumentGPR1)
+                        m_assembler.move(m_secondArgument, JSC::GPRInfo::argumentGPR1);
                 }
             } else {
                 // We know firstArgument is already in place, we can safely move secondArgument.
-                if (*m_secondArgument != JSC::GPRInfo::argumentGPR1)
-                    m_assembler.move(*m_secondArgument, JSC::GPRInfo::argumentGPR1);
+                if (m_secondArgument != JSC::GPRInfo::argumentGPR1)
+                    m_assembler.move(m_secondArgument, JSC::GPRInfo::argumentGPR1);
             }
-        } else if (m_firstArgument && *m_firstArgument != JSC::GPRInfo::argumentGPR0)
-            m_assembler.move(*m_firstArgument, JSC::GPRInfo::argumentGPR0);
+        } else if (m_argumentCount == 1) {
+            RELEASE_ASSERT(RegisterAllocator::isValidRegister(m_firstArgument));
+            if (m_firstArgument != JSC::GPRInfo::argumentGPR0)
+                m_assembler.move(m_firstArgument, JSC::GPRInfo::argumentGPR0);
+        }
 
         JSC::MacroAssembler::Call call = m_assembler.call();
         m_callRegistry.append(std::make_pair(call, m_functionAddress));
@@ -181,8 +190,9 @@
     Vector<StackAllocator::StackReference> m_savedRegisterStackReferences;
 
     JSC::FunctionPtr m_functionAddress;
-    const JSC::MacroAssembler::RegisterID* m_firstArgument;
-    const JSC::MacroAssembler::RegisterID* m_secondArgument;
+    unsigned m_argumentCount;
+    JSC::MacroAssembler::RegisterID m_firstArgument;
+    JSC::MacroAssembler::RegisterID m_secondArgument;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/cssjit/RegisterAllocator.h (166665 => 166666)


--- trunk/Source/WebCore/cssjit/RegisterAllocator.h	2014-04-02 21:06:33 UTC (rev 166665)
+++ trunk/Source/WebCore/cssjit/RegisterAllocator.h	2014-04-02 21:27:31 UTC (rev 166666)
@@ -113,6 +113,15 @@
 
     const Vector<JSC::MacroAssembler::RegisterID, registerCount>& allocatedRegisters() const { return m_allocatedRegisters; }
 
+    static bool isValidRegister(JSC::MacroAssembler::RegisterID registerID)
+    {
+#if CPU(X86_64)
+        return registerID >= JSC::X86Registers::eax && registerID <= JSC::X86Registers::r15;
+#else
+#error RegisterAllocator does not define the valid register range for the current architecture.
+#endif
+    }
+
 private:
     HashSet<unsigned, DefaultHash<unsigned>::Hash, WTF::UnsignedWithZeroKeyHashTraits<unsigned>> m_registers;
     Vector<JSC::MacroAssembler::RegisterID, registerCount> m_allocatedRegisters;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to