Title: [159288] trunk/Source/_javascript_Core
Revision
159288
Author
[email protected]
Date
2013-11-14 08:52:48 -0800 (Thu, 14 Nov 2013)

Log Message

REGRESSION (r159276): Fix lots of crashes for sh4 architecture.
https://bugs.webkit.org/show_bug.cgi?id=124347

Patch by Julien Brianceau <[email protected]> on 2013-11-14
Reviewed by Michael Saboff.

Since r159276, we have (t4 == a0 == r4) and (t5 == a1 == r5) in LLINT for sh4.
This leads to argument register trampling in cCallX macros, especially with cCall2
macro when arg1 == t4.

* llint/LowLevelInterpreter32_64.asm: Use a new "setargs" pseudo-op to setup arguments for sh4.
* offlineasm/instructions.rb:
* offlineasm/sh4.rb: Lower "setargs" pseudo-op to setup argument registers and prevent register trampling issues.

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (159287 => 159288)


--- trunk/Source/_javascript_Core/ChangeLog	2013-11-14 16:49:29 UTC (rev 159287)
+++ trunk/Source/_javascript_Core/ChangeLog	2013-11-14 16:52:48 UTC (rev 159288)
@@ -1,5 +1,20 @@
 2013-11-14  Julien Brianceau  <[email protected]>
 
+        REGRESSION (r159276): Fix lots of crashes for sh4 architecture.
+        https://bugs.webkit.org/show_bug.cgi?id=124347
+
+        Reviewed by Michael Saboff.
+
+        Since r159276, we have (t4 == a0 == r4) and (t5 == a1 == r5) in LLINT for sh4.
+        This leads to argument register trampling in cCallX macros, especially with cCall2
+        macro when arg1 == t4.
+
+        * llint/LowLevelInterpreter32_64.asm: Use a new "setargs" pseudo-op to setup arguments for sh4.
+        * offlineasm/instructions.rb:
+        * offlineasm/sh4.rb: Lower "setargs" pseudo-op to setup argument registers and prevent register trampling issues.
+
+2013-11-14  Julien Brianceau  <[email protected]>
+
         Fix build for sh4 architectures (broken since r159276).
         https://bugs.webkit.org/show_bug.cgi?id=124344
 

Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm (159287 => 159288)


--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm	2013-11-14 16:49:29 UTC (rev 159287)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm	2013-11-14 16:52:48 UTC (rev 159288)
@@ -105,10 +105,13 @@
         poke arg1, 0
         poke arg2, 1
         call function
-    elsif MIPS or SH4
+    elsif MIPS
         move arg1, a0
         move arg2, a1
         call function
+    elsif SH4
+        setargs arg1, arg2
+        call function
     elsif C_LOOP
         cloopCallSlowPath function, arg1, arg2
     else
@@ -130,12 +133,15 @@
         poke arg3, 2
         poke arg4, 3
         call function
-    elsif MIPS or SH4
+    elsif MIPS
         move arg1, a0
         move arg2, a1
         move arg3, a2
         move arg4, a3
         call function
+    elsif SH4
+        setargs arg1, arg2, arg3, arg4
+        call function
     elsif C_LOOP
         error
     else

Modified: trunk/Source/_javascript_Core/offlineasm/instructions.rb (159287 => 159288)


--- trunk/Source/_javascript_Core/offlineasm/instructions.rb	2013-11-14 16:49:29 UTC (rev 159287)
+++ trunk/Source/_javascript_Core/offlineasm/instructions.rb	2013-11-14 16:52:48 UTC (rev 159288)
@@ -288,7 +288,8 @@
     "loaddReversedAndIncrementAddress",
     "storedReversedAndDecrementAddress",
     "ldspr",
-    "stspr"
+    "stspr",
+    "setargs"
     ]
 
 CXX_INSTRUCTIONS =

Modified: trunk/Source/_javascript_Core/offlineasm/sh4.rb (159287 => 159288)


--- trunk/Source/_javascript_Core/offlineasm/sh4.rb	2013-11-14 16:49:29 UTC (rev 159287)
+++ trunk/Source/_javascript_Core/offlineasm/sh4.rb	2013-11-14 16:52:48 UTC (rev 159288)
@@ -563,6 +563,78 @@
 end
 
 
+#
+# Lowering of argument setup for SH4.
+# This phase avoids argument register trampling. For example, if a0 == t4:
+#
+# setargs t1, t4
+#
+# becomes:
+#
+# move t4, a1
+# move t1, a0
+#
+
+def sh4LowerArgumentSetup(list)
+    a0 = RegisterID.forName(codeOrigin, "a0")
+    a1 = RegisterID.forName(codeOrigin, "a1")
+    a2 = RegisterID.forName(codeOrigin, "a2")
+    a3 = RegisterID.forName(codeOrigin, "a3")
+    newList = []
+    list.each {
+        | node |
+        if node.is_a? Instruction
+            case node.opcode
+            when "setargs"
+                if node.operands.size == 2
+                    if node.operands[1].sh4Operand != a0.sh4Operand
+                        newList << Instruction.new(codeOrigin, "move", [node.operands[0], a0])
+                        newList << Instruction.new(codeOrigin, "move", [node.operands[1], a1])
+                    elsif node.operands[0].sh4Operand != a1.sh4Operand
+                        newList << Instruction.new(codeOrigin, "move", [node.operands[1], a1])
+                        newList << Instruction.new(codeOrigin, "move", [node.operands[0], a0])
+                    else
+                        # As (operands[0] == a1) and (operands[1] == a0), we just need to swap a0 and a1.
+                        newList << Instruction.new(codeOrigin, "xori", [a0, a1])
+                        newList << Instruction.new(codeOrigin, "xori", [a1, a0])
+                        newList << Instruction.new(codeOrigin, "xori", [a0, a1])
+                    end
+                elsif node.operands.size == 4
+                    # FIXME: We just raise an error if something is likely to go wrong for now.
+                    # It would be better to implement a recovering algorithm.
+                    if (node.operands[0].sh4Operand == a1.sh4Operand) or
+                        (node.operands[0].sh4Operand == a2.sh4Operand) or
+                        (node.operands[0].sh4Operand == a3.sh4Operand) or
+                        (node.operands[1].sh4Operand == a0.sh4Operand) or
+                        (node.operands[1].sh4Operand == a2.sh4Operand) or
+                        (node.operands[1].sh4Operand == a3.sh4Operand) or
+                        (node.operands[2].sh4Operand == a0.sh4Operand) or
+                        (node.operands[2].sh4Operand == a1.sh4Operand) or
+                        (node.operands[2].sh4Operand == a3.sh4Operand) or
+                        (node.operands[3].sh4Operand == a0.sh4Operand) or
+                        (node.operands[3].sh4Operand == a1.sh4Operand) or
+                        (node.operands[3].sh4Operand == a2.sh4Operand)
+                        raise "Potential argument register trampling detected."
+                    end
+
+                    newList << Instruction.new(codeOrigin, "move", [node.operands[0], a0])
+                    newList << Instruction.new(codeOrigin, "move", [node.operands[1], a1])
+                    newList << Instruction.new(codeOrigin, "move", [node.operands[2], a2])
+                    newList << Instruction.new(codeOrigin, "move", [node.operands[3], a3])
+                else
+                    raise "Invalid operands number (#{node.operands.size}) for setargs"
+                end
+            else
+                newList << node
+            end
+        else
+            newList << node
+        end
+    }
+    newList
+end
+
+
 class Sequence
     def getModifiedListSH4
         result = @list
@@ -613,6 +685,7 @@
         result = assignRegistersToTemporaries(result, :gpr, SH4_TMP_FPRS)
 
         result = sh4LowerConstPool(result)
+        result = sh4LowerArgumentSetup(result)
 
         return result
     end
@@ -883,7 +956,7 @@
                 else
                     $asm.puts "mov.l #{operands[0].labelref.asmLabel}, #{operands[1].sh4Operand}"
                 end
-            else
+            elsif operands[0].sh4Operand != operands[1].sh4Operand
                 $asm.puts "mov #{sh4Operands(operands)}"
             end
         when "leap"
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to