LLInt should do pointer caging
authorfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 3 Aug 2017 05:48:59 +0000 (05:48 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 3 Aug 2017 05:48:59 +0000 (05:48 +0000)
https://bugs.webkit.org/show_bug.cgi?id=175036

Reviewed by Keith Miller.

Implementing this in the LLInt was challenging because offlineasm did not previously know
how to load from globals. This teaches it how to do that on Darwin/x86_64, which happens
to be where the Gigacage is enabled right now.

* llint/LLIntOfflineAsmConfig.h:
* llint/LowLevelInterpreter64.asm:
* offlineasm/ast.rb:
* offlineasm/x86.rb:

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

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h
Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
Source/JavaScriptCore/offlineasm/ast.rb
Source/JavaScriptCore/offlineasm/x86.rb

index a2ea487..1179f9d 100644 (file)
@@ -1,5 +1,21 @@
 2017-08-02  Filip Pizlo  <fpizlo@apple.com>
 
+        LLInt should do pointer caging
+        https://bugs.webkit.org/show_bug.cgi?id=175036
+
+        Reviewed by Keith Miller.
+
+        Implementing this in the LLInt was challenging because offlineasm did not previously know
+        how to load from globals. This teaches it how to do that on Darwin/x86_64, which happens
+        to be where the Gigacage is enabled right now.
+
+        * llint/LLIntOfflineAsmConfig.h:
+        * llint/LowLevelInterpreter64.asm:
+        * offlineasm/ast.rb:
+        * offlineasm/x86.rb:
+
+2017-08-02  Filip Pizlo  <fpizlo@apple.com>
+
         Sweeping should only scribble when sweeping to free list
         https://bugs.webkit.org/show_bug.cgi?id=175105
 
index bf9fcff..3d150a8 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "LLIntCommon.h"
 #include <wtf/Assertions.h>
+#include <wtf/Gigacage.h>
 
 #if !ENABLE(JIT)
 #define OFFLINE_ASM_C_LOOP 1
 #else
 #define OFFLINE_ASM_EXECUTION_TRACING 0
 #endif
+
+#define OFFLINE_ASM_GIGACAGE_ENABLED GIGACAGE_ENABLED
index 4f16652..c7325c0 100644 (file)
@@ -376,6 +376,17 @@ macro checkSwitchToJITForLoop()
         end)
 end
 
+macro loadCaged(source, dest, scratch)
+    loadp source, dest
+    if GIGACAGE_ENABLED and not C_LOOP
+        loadp _g_gigacageBasePtr, scratch
+        btpz scratch, .done
+        andp constexpr GIGACAGE_MASK, dest
+        addp scratch, dest
+    .done:
+    end
+end
+
 macro loadVariable(operand, value)
     loadisFromInstruction(operand, value)
     loadq [cfr, value, 8], value
@@ -1198,9 +1209,7 @@ _llint_op_is_object:
 
 macro loadPropertyAtVariableOffset(propertyOffsetAsInt, objectAndStorage, value)
     bilt propertyOffsetAsInt, firstOutOfLineOffset, .isInline
-    # FIXME: Should do caging
-    # https://bugs.webkit.org/show_bug.cgi?id=175036
-    loadp JSObject::m_butterfly[objectAndStorage], objectAndStorage
+    loadCaged(JSObject::m_butterfly[objectAndStorage], objectAndStorage, value)
     negi propertyOffsetAsInt
     sxi2q propertyOffsetAsInt, propertyOffsetAsInt
     jmp .ready
@@ -1211,11 +1220,9 @@ macro loadPropertyAtVariableOffset(propertyOffsetAsInt, objectAndStorage, value)
 end
 
 
-macro storePropertyAtVariableOffset(propertyOffsetAsInt, objectAndStorage, value)
+macro storePropertyAtVariableOffset(propertyOffsetAsInt, objectAndStorage, value, scratch)
     bilt propertyOffsetAsInt, firstOutOfLineOffset, .isInline
-    # FIXME: Should do caging
-    # https://bugs.webkit.org/show_bug.cgi?id=175036
-    loadp JSObject::m_butterfly[objectAndStorage], objectAndStorage
+    loadCaged(JSObject::m_butterfly[objectAndStorage], objectAndStorage, scratch)
     negi propertyOffsetAsInt
     sxi2q propertyOffsetAsInt, propertyOffsetAsInt
     jmp .ready
@@ -1291,9 +1298,7 @@ _llint_op_get_array_length:
     btiz t2, IsArray, .opGetArrayLengthSlow
     btiz t2, IndexingShapeMask, .opGetArrayLengthSlow
     loadisFromInstruction(1, t1)
-    # FIXME: Should do caging
-    # https://bugs.webkit.org/show_bug.cgi?id=175036
-    loadp JSObject::m_butterfly[t3], t0
+    loadCaged(JSObject::m_butterfly[t3], t0, t2)
     loadi -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], t0
     bilt t0, 0, .opGetArrayLengthSlow
     orq tagTypeNumber, t0
@@ -1440,7 +1445,7 @@ _llint_op_put_by_id:
     loadisFromInstruction(3, t1)
     loadConstantOrVariable(t1, t2)
     loadisFromInstruction(5, t1)
-    storePropertyAtVariableOffset(t1, t0, t2)
+    storePropertyAtVariableOffset(t1, t0, t2, t3)
     writeBarrierOnOperands(1, 3)
     dispatch(constexpr op_put_by_id_length)
 
@@ -1476,9 +1481,7 @@ _llint_op_get_by_val:
     loadisFromInstruction(3, t3)
     loadConstantOrVariableInt32(t3, t1, .opGetByValSlow)
     sxi2q t1, t1
-    # FIXME: Should do caging
-    # https://bugs.webkit.org/show_bug.cgi?id=175036
-    loadp JSObject::m_butterfly[t0], t3
+    loadCaged(JSObject::m_butterfly[t0], t3, t5)
     andi IndexingShapeMask, t2
     bieq t2, Int32Shape, .opGetByValIsContiguous
     bineq t2, ContiguousShape, .opGetByValNotContiguous
@@ -1525,9 +1528,7 @@ _llint_op_get_by_val:
     bia t2, LastArrayType - FirstArrayType, .opGetByValSlow
     
     # Sweet, now we know that we have a typed array. Do some basic things now.
-    # FIXME: Should do caging
-    # https://bugs.webkit.org/show_bug.cgi?id=175036
-    loadp JSArrayBufferView::m_vector[t0], t3
+    loadCaged(JSArrayBufferView::m_vector[t0], t3, t5)
     biaeq t1, JSArrayBufferView::m_length[t0], .opGetByValSlow
     
     # Now bisect through the various types. Note that we can treat Uint8ArrayType and
@@ -1618,9 +1619,7 @@ macro putByVal(slowPath)
     loadisFromInstruction(2, t0)
     loadConstantOrVariableInt32(t0, t3, .opPutByValSlow)
     sxi2q t3, t3
-    # FIXME: Should do caging
-    # https://bugs.webkit.org/show_bug.cgi?id=175036
-    loadp JSObject::m_butterfly[t1], t0
+    loadCaged(JSObject::m_butterfly[t1], t0, t5)
     andi IndexingShapeMask, t2
     bineq t2, Int32Shape, .opPutByValNotInt32
     contiguousPutByVal(
@@ -2238,7 +2237,7 @@ macro putProperty()
     loadisFromInstruction(3, t1)
     loadConstantOrVariable(t1, t2)
     loadisFromInstruction(6, t1)
-    storePropertyAtVariableOffset(t1, t0, t2)
+    storePropertyAtVariableOffset(t1, t0, t2, t3)
 end
 
 macro putGlobalVariable()
index e2bc51d..de995b9 100644 (file)
@@ -928,7 +928,7 @@ class Instruction < Node
         when "globalAnnotation"
             $asm.putGlobalAnnotation
         when "emit"
-          $asm.puts "#{operands[0].dump}"
+            $asm.puts "#{operands[0].dump}"
         else
             raise "Unhandled opcode #{opcode} at #{codeOriginString}"
         end
index c73d0aa..4ee1f15 100644 (file)
@@ -247,6 +247,12 @@ def x86GPRName(name, kind)
     end
 end
 
+class Node
+    def x86LoadOperand(type, dst)
+        x86Operand(type)
+    end
+end
+
 class RegisterID
     def supports8BitOnX86
         case x86GPR
@@ -456,6 +462,12 @@ class LabelReference
     def x86CallOperand(kind)
         asmLabel
     end
+    def x86LoadOperand(kind, dst)
+        # FIXME: Implement this on platforms that aren't Mach-O.
+        # https://bugs.webkit.org/show_bug.cgi?id=175104
+        $asm.puts "movq #{asmLabel}@GOTPCREL(%rip), #{dst.x86Operand(:ptr)}"
+        "(#{dst.x86Operand(kind)})"
+    end
 end
 
 class LocalLabelReference
@@ -523,6 +535,10 @@ class Instruction
         }
         result.join(", ")
     end
+    
+    def x86LoadOperands(srcKind, dstKind)
+        orderOperands(operands[0].x86LoadOperand(srcKind, operands[1]), operands[1].x86Operand(dstKind))
+    end
 
     def x86Suffix(kind)
         if isIntelSyntax
@@ -927,45 +943,51 @@ class Instruction
             handleX86Op("xor#{x86Suffix(:ptr)}", :ptr)
         when "xorq"
             handleX86Op("xor#{x86Suffix(:quad)}", :quad)
-        when "loadi", "storei"
+        when "loadi"
+            $asm.puts "mov#{x86Suffix(:int)} #{x86LoadOperands(:int, :int)}"
+        when "storei"
             $asm.puts "mov#{x86Suffix(:int)} #{x86Operands(:int, :int)}"
         when "loadis"
             if isX64
                 if !isIntelSyntax
-                    $asm.puts "movslq #{x86Operands(:int, :quad)}"
+                    $asm.puts "movslq #{x86LoadOperands(:int, :quad)}"
                 else
-                    $asm.puts "movsxd #{x86Operands(:int, :quad)}"
+                    $asm.puts "movsxd #{x86LoadOperands(:int, :quad)}"
                 end
             else
-                $asm.puts "mov#{x86Suffix(:int)} #{x86Operands(:int, :int)}"
+                $asm.puts "mov#{x86Suffix(:int)} #{x86LoadOperands(:int, :int)}"
             end
-        when "loadp", "storep"
+        when "loadp"
+            $asm.puts "mov#{x86Suffix(:ptr)} #{x86LoadOperands(:ptr, :ptr)}"
+        when "storep"
             $asm.puts "mov#{x86Suffix(:ptr)} #{x86Operands(:ptr, :ptr)}"
-        when "loadq", "storeq"
+        when "loadq"
+            $asm.puts "mov#{x86Suffix(:quad)} #{x86LoadOperands(:quad, :quad)}"
+        when "storeq"
             $asm.puts "mov#{x86Suffix(:quad)} #{x86Operands(:quad, :quad)}"
         when "loadb"
             if !isIntelSyntax
-                $asm.puts "movzbl #{orderOperands(operands[0].x86Operand(:byte), operands[1].x86Operand(:int))}"
+                $asm.puts "movzbl #{x86LoadOperands(:byte, :int)}"
             else
-                $asm.puts "movzx #{orderOperands(operands[0].x86Operand(:byte), operands[1].x86Operand(:int))}"
+                $asm.puts "movzx #{x86LoadOperands(:byte, :int)}"
             end
         when "loadbs"
             if !isIntelSyntax
-                $asm.puts "movsbl #{orderOperands(operands[0].x86Operand(:byte), operands[1].x86Operand(:int))}"
+                $asm.puts "movsbl #{x86LoadOperands(:byte, :int)}"
             else
-                $asm.puts "movsx #{orderOperands(operands[0].x86Operand(:byte), operands[1].x86Operand(:int))}"
+                $asm.puts "movsx #{x86LoadOperands(:byte, :int)}"
             end
         when "loadh"
             if !isIntelSyntax
-                $asm.puts "movzwl #{orderOperands(operands[0].x86Operand(:half), operands[1].x86Operand(:int))}"
+                $asm.puts "movzwl #{x86LoadOperands(:half, :int)}"
             else
-                $asm.puts "movzx #{orderOperands(operands[0].x86Operand(:half), operands[1].x86Operand(:int))}"
+                $asm.puts "movzx #{x86LoadOperands(:half, :int)}"
             end
         when "loadhs"
             if !isIntelSyntax
-                $asm.puts "movswl #{orderOperands(operands[0].x86Operand(:half), operands[1].x86Operand(:int))}"
+                $asm.puts "movswl #{x86LoadOperands(:half, :int)}"
             else
-                $asm.puts "movsx #{orderOperands(operands[0].x86Operand(:half), operands[1].x86Operand(:int))}"
+                $asm.puts "movsx #{x86LoadOperands(:half, :int)}"
             end
         when "storeb"
             $asm.puts "mov#{x86Suffix(:byte)} #{x86Operands(:byte, :byte)}"