Reenable Gigacage on ARM64.
authorkeith_miller@apple.com <keith_miller@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 2 Jun 2019 20:02:00 +0000 (20:02 +0000)
committerkeith_miller@apple.com <keith_miller@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 2 Jun 2019 20:02:00 +0000 (20:02 +0000)
https://bugs.webkit.org/show_bug.cgi?id=198453

Reviewed by Filip Pizlo.

Source/bmalloc:

* bmalloc/Gigacage.h:

Source/JavaScriptCore:

This patch adds back Gigacaging on Apple's ARM64 ports. Unlike the
old Gigacage however, arm64e uses both Gigacaging and PAC. Since
Gigacaging would otherwise strip a PAC failed authenticate bit we
force a load of the pointer into some garbage register.

* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::jumpForTypedArrayIsNeuteredIfOutOfBounds):
(JSC::DFG::SpeculativeJIT::cageTypedArrayStorage):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNewTypedArray):
(JSC::FTL::DFG::LowerDFGToB3::untagArrayPtr):
(JSC::FTL::DFG::LowerDFGToB3::caged):
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::cageConditionally):
* llint/LowLevelInterpreter64.asm:

Source/WTF:

* wtf/CagedPtr.h:
(WTF::CagedPtr::authenticatingLoad):
(WTF::CagedPtr::get const):
(WTF::CagedPtr::getMayBeNull const):

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

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
Source/JavaScriptCore/jit/AssemblyHelpers.h
Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
Source/WTF/ChangeLog
Source/WTF/wtf/CagedPtr.h
Source/bmalloc/ChangeLog
Source/bmalloc/bmalloc/Gigacage.h

index 90a4119..3c786e1 100644 (file)
@@ -1,3 +1,26 @@
+2019-06-02  Keith Miller  <keith_miller@apple.com>
+
+        Reenable Gigacage on ARM64.
+        https://bugs.webkit.org/show_bug.cgi?id=198453
+
+        Reviewed by Filip Pizlo.
+
+        This patch adds back Gigacaging on Apple's ARM64 ports. Unlike the
+        old Gigacage however, arm64e uses both Gigacaging and PAC. Since
+        Gigacaging would otherwise strip a PAC failed authenticate bit we
+        force a load of the pointer into some garbage register.
+
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::jumpForTypedArrayIsNeuteredIfOutOfBounds):
+        (JSC::DFG::SpeculativeJIT::cageTypedArrayStorage):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileNewTypedArray):
+        (JSC::FTL::DFG::LowerDFGToB3::untagArrayPtr):
+        (JSC::FTL::DFG::LowerDFGToB3::caged):
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::cageConditionally):
+        * llint/LowLevelInterpreter64.asm:
+
 2019-06-02  Tadeu Zagallo  <tzagallo@apple.com>
 
         CachedMetadataTable::decode leaks empty tables
index d0410b3..522214a 100644 (file)
@@ -2873,7 +2873,7 @@ JITCompiler::Jump SpeculativeJIT::jumpForTypedArrayIsNeuteredIfOutOfBounds(Node*
                 TrustedImm32(WastefulTypedArray));
 
             JITCompiler::Jump hasNullVector;
-#if !GIGACAGE_ENABLED && CPU(ARM64E)
+#if CPU(ARM64E)
             {
                 GPRReg scratch = m_jit.scratchRegister();
                 DisallowMacroScratchRegisterUsage disallowScratch(m_jit);
@@ -2882,7 +2882,7 @@ JITCompiler::Jump SpeculativeJIT::jumpForTypedArrayIsNeuteredIfOutOfBounds(Node*
                 m_jit.removeArrayPtrTag(scratch);
                 hasNullVector = m_jit.branchTestPtr(MacroAssembler::Zero, scratch);
             }
-#else // !GIGACAGE_ENABLED && CPU(ARM64E)
+#else // CPU(ARM64E)
             hasNullVector = m_jit.branchTestPtr(
                 MacroAssembler::Zero,
                 MacroAssembler::Address(base, JSArrayBufferView::offsetOfVector()));
@@ -6719,6 +6719,14 @@ void SpeculativeJIT::compileConstantStoragePointer(Node* node)
 
 void SpeculativeJIT::cageTypedArrayStorage(GPRReg baseReg, GPRReg storageReg)
 {
+#if CPU(ARM64E)
+    m_jit.untagArrayPtr(MacroAssembler::Address(baseReg, JSArrayBufferView::offsetOfLength()), storageReg);
+    m_jit.loadPtr(storageReg, m_jit.scratchRegister());
+#else
+    UNUSED_PARAM(baseReg);
+    UNUSED_PARAM(storageReg);
+#endif
+
 #if GIGACAGE_ENABLED
     UNUSED_PARAM(baseReg);
     if (!Gigacage::shouldBeEnabled())
@@ -6732,11 +6740,6 @@ void SpeculativeJIT::cageTypedArrayStorage(GPRReg baseReg, GPRReg storageReg)
     }
     
     m_jit.cage(Gigacage::Primitive, storageReg);
-#elif CPU(ARM64E)
-    m_jit.untagArrayPtr(MacroAssembler::Address(baseReg, JSArrayBufferView::offsetOfLength()), storageReg);
-#else
-    UNUSED_PARAM(baseReg);
-    UNUSED_PARAM(storageReg);
 #endif
 }
 
index 5e28a1a..145132f 100644 (file)
@@ -6463,7 +6463,7 @@ private:
                 m_out.int64Zero,
                 m_heaps.typedArrayProperties);
 
-#if !GIGACAGE_ENABLED && CPU(ARM64E)
+#if CPU(ARM64E)
             {
                 LValue sizePtr = m_out.zeroExtPtr(size);
                 PatchpointValue* authenticate = m_out.patchpoint(pointerType());
@@ -14108,9 +14108,12 @@ private:
         PatchpointValue* authenticate = m_out.patchpoint(pointerType());
         authenticate->appendSomeRegister(ptr);
         authenticate->append(size, B3::ValueRep(B3::ValueRep::SomeLateRegister));
+        authenticate->numGPScratchRegisters = 1;
         authenticate->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
             jit.move(params[1].gpr(), params[0].gpr());
             jit.untagArrayPtr(params[2].gpr(), params[0].gpr());
+            // Force a load to check authentication. before it is cleared by Gigacaging later.
+            jit.loadPtr(params[0].gpr(), params.gpScratch(0));
         });
         return authenticate;
 #else
@@ -14135,6 +14138,16 @@ private:
 
     LValue caged(Gigacage::Kind kind, LValue ptr, LValue base)
     {
+#if CPU(ARM64E)
+        if (kind == Gigacage::Primitive) {
+            LValue size = m_out.load32(base, m_heaps.JSArrayBufferView_length);
+            ptr = untagArrayPtr(ptr, size);
+        }
+#else
+        UNUSED_PARAM(kind);
+        UNUSED_PARAM(base);
+#endif
+
 #if GIGACAGE_ENABLED
         UNUSED_PARAM(base);
         if (!Gigacage::isEnabled(kind))
@@ -14165,17 +14178,6 @@ private:
         // and possibly other smart things if we want to be able to remove this opaque.
         // https://bugs.webkit.org/show_bug.cgi?id=175493
         return m_out.opaque(result);
-#elif CPU(ARM64E)
-        if (kind == Gigacage::Primitive) {
-            LValue size = m_out.load32(base, m_heaps.JSArrayBufferView_length);
-            return untagArrayPtr(ptr, size);
-        }
-
-        return ptr;
-#else
-        UNUSED_PARAM(kind);
-        UNUSED_PARAM(base);
-        return ptr;
 #endif
     }
     
index d9268e8..6075071 100644 (file)
@@ -1571,6 +1571,18 @@ public:
     
     void cageConditionally(Gigacage::Kind kind, GPRReg storage, GPRReg scratchOrLength)
     {
+#if CPU(ARM64E)
+        if (kind == Gigacage::Primitive) {
+            untagArrayPtr(scratchOrLength, storage);
+            // Force a load to trap on authentication failure. storage shouldn't be null here.
+            loadPtr(storage, scratchOrLength);
+        }
+#else
+        UNUSED_PARAM(kind);
+        UNUSED_PARAM(storage);
+        UNUSED_PARAM(scratchOrLength);
+#endif
+
 #if GIGACAGE_ENABLED
         if (!Gigacage::isEnabled(kind))
             return;
@@ -1583,13 +1595,6 @@ public:
         andPtr(TrustedImmPtr(Gigacage::mask(kind)), storage);
         addPtr(scratchOrLength, storage);
         done.link(this);
-#elif CPU(ARM64E)
-        if (kind == Gigacage::Primitive)
-            untagArrayPtr(scratchOrLength, storage);
-#else
-        UNUSED_PARAM(kind);
-        UNUSED_PARAM(storage);
-        UNUSED_PARAM(scratchOrLength);
 #endif
     }
 
index 6aaf0dd..4ce82d8 100644 (file)
@@ -434,10 +434,13 @@ end
 
 macro loadCagedPrimitive(source, dest, scratchOrLength)
     loadp source, dest
+    if ARM64E
+        untagArrayPtr scratchOrLength, dest
+        # Force a load to check PAC before we clear it below.
+        loadp [dest], scratchOrLength
+    end
     if GIGACAGE_ENABLED
         uncage(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr Gigacage::primitiveGigacageMask, dest, scratchOrLength)
-    elsif ARM64E
-        untagArrayPtr scratchOrLength, dest
     end
 end
 
index 1289c8b..8346686 100644 (file)
@@ -1,3 +1,15 @@
+2019-06-02  Keith Miller  <keith_miller@apple.com>
+
+        Reenable Gigacage on ARM64.
+        https://bugs.webkit.org/show_bug.cgi?id=198453
+
+        Reviewed by Filip Pizlo.
+
+        * wtf/CagedPtr.h:
+        (WTF::CagedPtr::authenticatingLoad):
+        (WTF::CagedPtr::get const):
+        (WTF::CagedPtr::getMayBeNull const):
+
 2019-05-31  Alex Christensen  <achristensen@webkit.org>
 
         URLParser::parseIPv6Host should properly parse 0's around compression
index 71ec51e..ecc9e00 100644 (file)
@@ -35,6 +35,18 @@ constexpr bool tagCagedPtr = true;
 
 template<Gigacage::Kind passedKind, typename T, bool shouldTag = false, typename PtrTraits = DumbPtrTraits<T>>
 class CagedPtr {
+#if CPU(ARM64E)
+    static void authenticatingLoad(T* ptr)
+    {
+        double result;
+        asm volatile("ldr %[out], [%[in]]"
+            : [out] "=&r"(result)
+            : [in] "r"(ptr) :);
+    }
+#else
+    static void authenticatingLoad(T*) { }
+#endif
+
 public:
     static constexpr Gigacage::Kind kind = passedKind;
 
@@ -52,16 +64,21 @@ public:
     {
         ASSERT(m_ptr);
         T* ptr = PtrTraits::unwrap(m_ptr);
-        if (shouldTag)
+        if (shouldTag) {
             ptr = untagArrayPtr(ptr, size);
+            authenticatingLoad(ptr);
+        }
         return Gigacage::caged(kind, ptr);
     }
 
     T* getMayBeNull(unsigned size) const
     {
         T* ptr = PtrTraits::unwrap(m_ptr);
-        if (shouldTag)
+        if (shouldTag) {
             ptr = untagArrayPtr(ptr, size);
+            if (ptr)
+                authenticatingLoad(ptr);
+        }
         return Gigacage::cagedMayBeNull(kind, ptr);
     }
 
index f5ce05b..813d572 100644 (file)
@@ -1,3 +1,12 @@
+2019-06-02  Keith Miller  <keith_miller@apple.com>
+
+        Reenable Gigacage on ARM64.
+        https://bugs.webkit.org/show_bug.cgi?id=198453
+
+        Reviewed by Filip Pizlo.
+
+        * bmalloc/Gigacage.h:
+
 2019-05-30  Don Olmstead  <don.olmstead@sony.com>
 
         [CMake] Add WEBKIT_FRAMEWORK_TARGET macro
index 76d72df..a37d0ba 100644 (file)
@@ -34,7 +34,8 @@
 #include <cstddef>
 #include <inttypes.h>
 
-#if ((BOS(DARWIN) || BOS(LINUX)) && BCPU(X86_64))
+#if ((BOS(DARWIN) || BOS(LINUX)) && \
+    (BCPU(X86_64) || (BCPU(ARM64) && !defined(__ILP32__) && (!BPLATFORM(IOS_FAMILY) || BPLATFORM(IOS)))))
 #define GIGACAGE_ENABLED 1
 #else
 #define GIGACAGE_ENABLED 0