Title: [246150] trunk/Source
Revision
246150
Author
[email protected]
Date
2019-06-06 06:20:56 -0700 (Thu, 06 Jun 2019)

Log Message

Reenable Gigacage on ARM64.
https://bugs.webkit.org/show_bug.cgi?id=198453

Reviewed by Michael Saboff.

Source/bmalloc:

* bmalloc/Gigacage.h:

Source/_javascript_Core:

This patch adds back Gigacaging on Apple's ARM64 ports. Unlike the
old Gigacage however, arm64e uses both Gigacaging and PAC. In
order to ensure the PAC bits are not stripped in the caging
process we use the bit field insert instruction to take the low
bits from caging and the high bits from the PAC authentication.

* assembler/MacroAssemblerARM64.h:
(JSC::MacroAssemblerARM64::bitFieldInsert64):
* assembler/MacroAssemblerARM64E.h:
* assembler/testmasm.cpp:
(JSC::testCagePreservesPACFailureBit):
(JSC::run):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::jumpForTypedArrayIsNeuteredIfOutOfBounds):
(JSC::DFG::SpeculativeJIT::cageTypedArrayStorage):
(JSC::DFG::SpeculativeJIT::compileGetTypedArrayByteOffset):
(JSC::DFG::SpeculativeJIT::compileNewTypedArrayWithSize):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNewTypedArray):
(JSC::FTL::DFG::LowerDFGToB3::caged):
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::cageWithoutUntaging):
(JSC::AssemblyHelpers::cageConditionally):
(JSC::AssemblyHelpers::cage): Deleted.
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emitIntTypedArrayGetByVal):
(JSC::JIT::emitFloatTypedArrayGetByVal):
(JSC::JIT::emitIntTypedArrayPutByVal):
(JSC::JIT::emitFloatTypedArrayPutByVal):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter64.asm:
* offlineasm/arm64.rb:
* offlineasm/instructions.rb:
* offlineasm/registers.rb:
* wasm/WasmAirIRGenerator.cpp:
(JSC::Wasm::AirIRGenerator::restoreWebAssemblyGlobalState):
(JSC::Wasm::AirIRGenerator::addCallIndirect):
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::restoreWebAssemblyGlobalState):
(JSC::Wasm::B3IRGenerator::addCallIndirect):
* wasm/WasmBinding.cpp:
(JSC::Wasm::wasmToWasm):
* wasm/js/JSToWasm.cpp:
(JSC::Wasm::createJSToWasmWrapper):
* wasm/js/WebAssemblyFunction.cpp:
(JSC::WebAssemblyFunction::jsCallEntrypointSlow):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (246149 => 246150)


--- trunk/Source/_javascript_Core/ChangeLog	2019-06-06 11:34:10 UTC (rev 246149)
+++ trunk/Source/_javascript_Core/ChangeLog	2019-06-06 13:20:56 UTC (rev 246150)
@@ -1,3 +1,57 @@
+2019-06-06  Keith Miller  <[email protected]>
+
+        Reenable Gigacage on ARM64.
+        https://bugs.webkit.org/show_bug.cgi?id=198453
+
+        Reviewed by Michael Saboff.
+
+        This patch adds back Gigacaging on Apple's ARM64 ports. Unlike the
+        old Gigacage however, arm64e uses both Gigacaging and PAC. In
+        order to ensure the PAC bits are not stripped in the caging
+        process we use the bit field insert instruction to take the low
+        bits from caging and the high bits from the PAC authentication.
+
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::bitFieldInsert64):
+        * assembler/MacroAssemblerARM64E.h:
+        * assembler/testmasm.cpp:
+        (JSC::testCagePreservesPACFailureBit):
+        (JSC::run):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::jumpForTypedArrayIsNeuteredIfOutOfBounds):
+        (JSC::DFG::SpeculativeJIT::cageTypedArrayStorage):
+        (JSC::DFG::SpeculativeJIT::compileGetTypedArrayByteOffset):
+        (JSC::DFG::SpeculativeJIT::compileNewTypedArrayWithSize):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileNewTypedArray):
+        (JSC::FTL::DFG::LowerDFGToB3::caged):
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::cageWithoutUntaging):
+        (JSC::AssemblyHelpers::cageConditionally):
+        (JSC::AssemblyHelpers::cage): Deleted.
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emitIntTypedArrayGetByVal):
+        (JSC::JIT::emitFloatTypedArrayGetByVal):
+        (JSC::JIT::emitIntTypedArrayPutByVal):
+        (JSC::JIT::emitFloatTypedArrayPutByVal):
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * offlineasm/arm64.rb:
+        * offlineasm/instructions.rb:
+        * offlineasm/registers.rb:
+        * wasm/WasmAirIRGenerator.cpp:
+        (JSC::Wasm::AirIRGenerator::restoreWebAssemblyGlobalState):
+        (JSC::Wasm::AirIRGenerator::addCallIndirect):
+        * wasm/WasmB3IRGenerator.cpp:
+        (JSC::Wasm::B3IRGenerator::restoreWebAssemblyGlobalState):
+        (JSC::Wasm::B3IRGenerator::addCallIndirect):
+        * wasm/WasmBinding.cpp:
+        (JSC::Wasm::wasmToWasm):
+        * wasm/js/JSToWasm.cpp:
+        (JSC::Wasm::createJSToWasmWrapper):
+        * wasm/js/WebAssemblyFunction.cpp:
+        (JSC::WebAssemblyFunction::jsCallEntrypointSlow):
+
 2019-06-06  Michael Saboff  <[email protected]>
 
         [ARM64E]: Add disassembler support for authenticated instructions

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.h (246149 => 246150)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.h	2019-06-06 11:34:10 UTC (rev 246149)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.h	2019-06-06 13:20:56 UTC (rev 246150)
@@ -2526,6 +2526,15 @@
         m_assembler.fcsel<64>(dest, thenCase, elseCase, ARM64Condition(cond));
     }
 
+    // Bit field operations:
+
+    // destBitOffset is the top bit of the destination where the bits should be copied to. Zero is the lowest order bit.
+    void bitFieldInsert64(RegisterID source, unsigned destBitOffset, unsigned width, RegisterID dest)
+    {
+        ASSERT(width <= 64 - destBitOffset && destBitOffset < 64);
+        m_assembler.bfi<64>(dest, source, destBitOffset, width);
+    }
+
     // Forwards / external control flow operations:
     //
     // This set of jump and conditional branch operations return a Jump

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64E.h (246149 => 246150)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64E.h	2019-06-06 11:34:10 UTC (rev 246149)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64E.h	2019-06-06 13:20:56 UTC (rev 246150)
@@ -39,6 +39,8 @@
 
 class MacroAssemblerARM64E : public MacroAssemblerARM64 {
 public:
+    static constexpr unsigned numberOfPACBits = 25;
+
     ALWAYS_INLINE void tagReturnAddress()
     {
         tagPtr(ARM64Registers::sp, ARM64Registers::lr);

Modified: trunk/Source/_javascript_Core/assembler/testmasm.cpp (246149 => 246150)


--- trunk/Source/_javascript_Core/assembler/testmasm.cpp	2019-06-06 11:34:10 UTC (rev 246149)
+++ trunk/Source/_javascript_Core/assembler/testmasm.cpp	2019-06-06 13:20:56 UTC (rev 246150)
@@ -39,6 +39,7 @@
 #include <wtf/Function.h>
 #include <wtf/Lock.h>
 #include <wtf/NumberOfCores.h>
+#include <wtf/PtrTag.h>
 #include <wtf/Threading.h>
 #include <wtf/text/StringCommon.h>
 
@@ -109,6 +110,15 @@
         CRASH();                                                        \
     } while (false)
 
+#define CHECK_NOT_EQ(_actual, _expected) do {                               \
+        if ((_actual) != (_expected))                                   \
+            break;                                                      \
+        crashLock.lock();                                               \
+        dataLog("FAILED while testing " #_actual ": expected not: ", _expected, ", actual: ", _actual, "\n"); \
+        WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, "CHECK_NOT_EQ("#_actual ", " #_expected ")"); \
+        CRASH();                                                        \
+    } while (false)
+
 #if ENABLE(MASM_PROBE)
 bool isPC(MacroAssembler::RegisterID id)
 {
@@ -1003,6 +1013,47 @@
 #endif
 }
 
+static void testCagePreservesPACFailureBit()
+{
+    auto cage = compile([] (CCallHelpers& jit) {
+        jit.emitFunctionPrologue();
+        jit.cageConditionally(Gigacage::Primitive, GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, GPRInfo::argumentGPR2);
+        jit.move(GPRInfo::argumentGPR0, GPRInfo::returnValueGPR);
+        jit.emitFunctionEpilogue();
+        jit.ret();
+    });
+
+    void* ptr = Gigacage::tryMalloc(Gigacage::Primitive, 1);
+    void* taggedPtr = tagArrayPtr(ptr, 1);
+    dataLogLn("starting test");
+    if (isARM64E()) {
+        // FIXME: This won't work if authentication failures trap but I don't know how to test for that right now.
+        CHECK_NOT_EQ(invoke<void*>(cage, taggedPtr, 2), ptr);
+    } else
+        CHECK_EQ(invoke<void*>(cage, taggedPtr, 2), ptr);
+
+    CHECK_EQ(invoke<void*>(cage, taggedPtr, 1), ptr);
+
+    auto cageWithoutAuthentication = compile([] (CCallHelpers& jit) {
+        jit.emitFunctionPrologue();
+        jit.cageWithoutUntaging(Gigacage::Primitive, GPRInfo::argumentGPR0);
+        jit.move(GPRInfo::argumentGPR0, GPRInfo::returnValueGPR);
+        jit.emitFunctionEpilogue();
+        jit.ret();
+    });
+
+    if (isARM64E()) {
+        // FIXME: This won't work if authentication failures trap but I don't know how to test for that right now.
+        CHECK_NOT_EQ(invoke<void*>(cageWithoutAuthentication, untagArrayPtr(taggedPtr, 2)), ptr);
+    } else
+        CHECK_EQ(invoke<void*>(cageWithoutAuthentication, untagArrayPtr(taggedPtr, 2)), ptr);
+
+    CHECK_EQ(untagArrayPtr(taggedPtr, 1), ptr);
+    CHECK_EQ(invoke<void*>(cageWithoutAuthentication, untagArrayPtr(taggedPtr, 1)), ptr);
+
+    Gigacage::free(Gigacage::Primitive, ptr);
+}
+
 #define RUN(test) do {                          \
         if (!shouldRun(#test))                  \
             break;                              \
@@ -1088,6 +1139,8 @@
     RUN(testMoveDoubleConditionally32());
     RUN(testMoveDoubleConditionally64());
 
+    RUN(testCagePreservesPACFailureBit());
+
     if (tasks.isEmpty())
         usage();
 

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (246149 => 246150)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2019-06-06 11:34:10 UTC (rev 246149)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2019-06-06 13:20:56 UTC (rev 246150)
@@ -2873,7 +2873,7 @@
                 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 @@
                 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()));
@@ -6760,6 +6760,13 @@
 
 void SpeculativeJIT::cageTypedArrayStorage(GPRReg baseReg, GPRReg storageReg)
 {
+#if CPU(ARM64E)
+    m_jit.untagArrayPtr(MacroAssembler::Address(baseReg, JSArrayBufferView::offsetOfLength()), storageReg);
+#else
+    UNUSED_PARAM(baseReg);
+    UNUSED_PARAM(storageReg);
+#endif
+
 #if GIGACAGE_ENABLED
     UNUSED_PARAM(baseReg);
     if (!Gigacage::shouldBeEnabled())
@@ -6772,12 +6779,7 @@
             return;
     }
     
-    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);
+    m_jit.cageWithoutUntaging(Gigacage::Primitive, storageReg);
 #endif
 }
 
@@ -6841,7 +6843,7 @@
     JITCompiler::Jump nullVector = m_jit.branchTestPtr(JITCompiler::Zero, vectorGPR);
 
     m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::butterflyOffset()), dataGPR);
-    m_jit.cage(Gigacage::JSValue, dataGPR);
+    m_jit.cageWithoutUntaging(Gigacage::JSValue, dataGPR);
 
     cageTypedArrayStorage(baseGPR, vectorGPR);
 
@@ -9845,7 +9847,7 @@
         MacroAssembler::BaseIndex(storageGPR, scratchGPR, MacroAssembler::TimesFour));
     m_jit.branchTest32(MacroAssembler::NonZero, scratchGPR).linkTo(loop, &m_jit);
     done.link(&m_jit);
-#if !GIGACAGE_ENABLED && CPU(ARM64E)
+#if CPU(ARM64E)
     // sizeGPR is still boxed as a number and there is no 32-bit variant of the PAC instructions.
     m_jit.zeroExtend32ToPtr(sizeGPR, scratchGPR);
     m_jit.tagArrayPtr(scratchGPR, storageGPR);

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (246149 => 246150)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2019-06-06 11:34:10 UTC (rev 246149)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2019-06-06 13:20:56 UTC (rev 246150)
@@ -6485,7 +6485,7 @@
                 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());
@@ -14157,6 +14157,16 @@
 
     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))
@@ -14175,6 +14185,18 @@
         LValue masked = m_out.bitAnd(ptr, mask);
         LValue result = m_out.add(masked, basePtr);
 
+#if CPU(ARM64E)
+        {
+            PatchpointValue* merge = m_out.patchpoint(pointerType());
+            merge->append(result, B3::ValueRep(B3::ValueRep::SomeLateRegister));
+            merge->appendSomeRegister(ptr);
+            merge->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
+                jit.move(params[2].gpr(), params[0].gpr());
+                jit.bitFieldInsert64(params[1].gpr(), 0, 64 - MacroAssembler::numberOfPACBits, params[0].gpr());
+            });
+            result = merge;
+        }
+#endif
         // Make sure that B3 doesn't try to do smart reassociation of these pointer bits.
         // FIXME: In an ideal world, B3 would not do harmful reassociations, and if it did, it would be able
         // to undo them during constant hoisting and regalloc. As it stands, if you remove this then Octane
@@ -14187,17 +14209,6 @@
         // 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
     }
     

Modified: trunk/Source/_javascript_Core/jit/AssemblyHelpers.h (246149 => 246150)


--- trunk/Source/_javascript_Core/jit/AssemblyHelpers.h	2019-06-06 11:34:10 UTC (rev 246149)
+++ trunk/Source/_javascript_Core/jit/AssemblyHelpers.h	2019-06-06 13:20:56 UTC (rev 246150)
@@ -1554,43 +1554,74 @@
         storeFence();
         ok.link(this);
     }
-    
-    void cage(Gigacage::Kind kind, GPRReg storage)
+
+    void cageWithoutUntaging(Gigacage::Kind kind, GPRReg storage)
     {
 #if GIGACAGE_ENABLED
         if (!Gigacage::isEnabled(kind))
             return;
-        
+
+#if CPU(ARM64E)
+        RegisterID tempReg = InvalidGPRReg;
+        if (kind == Gigacage::Primitive) {
+            tempReg = getCachedMemoryTempRegisterIDAndInvalidate();
+            move(storage, tempReg);
+            // Flip the registers since bitFieldInsert only inserts into the low bits.
+            std::swap(storage, tempReg);
+        }
+#endif
         andPtr(TrustedImmPtr(Gigacage::mask(kind)), storage);
         addPtr(TrustedImmPtr(Gigacage::basePtr(kind)), storage);
+#if CPU(ARM64E)
+        if (kind == Gigacage::Primitive)
+            bitFieldInsert64(storage, 0, 64 - numberOfPACBits, tempReg);
+#endif
+
 #else
         UNUSED_PARAM(kind);
         UNUSED_PARAM(storage);
 #endif
     }
-    
-    void cageConditionally(Gigacage::Kind kind, GPRReg storage, GPRReg scratchOrLength)
+
+    // length may be the same register as scratch.
+    void cageConditionally(Gigacage::Kind kind, GPRReg storage, GPRReg length, GPRReg scratch)
     {
+#if CPU(ARM64E)
+        if (kind == Gigacage::Primitive)
+            untagArrayPtr(length, storage);
+#else
+        UNUSED_PARAM(kind);
+        UNUSED_PARAM(storage);
+        UNUSED_PARAM(length);
+#endif
+
 #if GIGACAGE_ENABLED
         if (!Gigacage::isEnabled(kind))
             return;
         
         if (kind != Gigacage::Primitive || Gigacage::isDisablingPrimitiveGigacageDisabled())
-            return cage(kind, storage);
-        
-        loadPtr(&Gigacage::basePtr(kind), scratchOrLength);
-        Jump done = branchTestPtr(Zero, scratchOrLength);
-        andPtr(TrustedImmPtr(Gigacage::mask(kind)), storage);
-        addPtr(scratchOrLength, storage);
-        done.link(this);
-#elif CPU(ARM64E)
-        if (kind == Gigacage::Primitive)
-            untagArrayPtr(scratchOrLength, storage);
+            cageWithoutUntaging(kind, storage);
+        else {
+            loadPtr(&Gigacage::basePtr(kind), scratch);
+            Jump done = branchTestPtr(Zero, scratch);
+#if CPU(ARM64E)
+            auto tempReg = getCachedMemoryTempRegisterIDAndInvalidate();
+            move(storage, tempReg);
+            andPtr(TrustedImmPtr(Gigacage::mask(kind)), tempReg);
+            addPtr(scratch, tempReg);
+            bitFieldInsert64(tempReg, 0, 64 - numberOfPACBits, storage);
 #else
-        UNUSED_PARAM(kind);
-        UNUSED_PARAM(storage);
-        UNUSED_PARAM(scratchOrLength);
+            andPtr(TrustedImmPtr(Gigacage::mask(kind)), storage);
+            addPtr(scratch, storage);
 #endif
+            done.link(this);
+
+
+        }
+#else
+        UNUSED_PARAM(scratch);
+#endif
+
     }
 
     void emitComputeButterflyIndexingMask(GPRReg vectorLengthGPR, GPRReg scratchGPR, GPRReg resultGPR)

Modified: trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp (246149 => 246150)


--- trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp	2019-06-06 11:34:10 UTC (rev 246149)
+++ trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp	2019-06-06 13:20:56 UTC (rev 246150)
@@ -1672,7 +1672,7 @@
     load32(Address(base, JSArrayBufferView::offsetOfLength()), scratch2);
     slowCases.append(branch32(AboveOrEqual, property, scratch2));
     loadPtr(Address(base, JSArrayBufferView::offsetOfVector()), scratch);
-    cageConditionally(Gigacage::Primitive, scratch, scratch2);
+    cageConditionally(Gigacage::Primitive, scratch, scratch2, scratch2);
 
     switch (elementSize(type)) {
     case 1:
@@ -1736,7 +1736,7 @@
     load32(Address(base, JSArrayBufferView::offsetOfLength()), scratch2);
     slowCases.append(branch32(AboveOrEqual, property, scratch2));
     loadPtr(Address(base, JSArrayBufferView::offsetOfVector()), scratch);
-    cageConditionally(Gigacage::Primitive, scratch, scratch2);
+    cageConditionally(Gigacage::Primitive, scratch, scratch2, scratch2);
     
     switch (elementSize(type)) {
     case 4:
@@ -1801,7 +1801,7 @@
     // We would be loading this into base as in get_by_val, except that the slow
     // path expects the base to be unclobbered.
     loadPtr(Address(base, JSArrayBufferView::offsetOfVector()), lateScratch);
-    cageConditionally(Gigacage::Primitive, lateScratch, lateScratch2);
+    cageConditionally(Gigacage::Primitive, lateScratch, lateScratch2, lateScratch2);
     
     if (isClamped(type)) {
         ASSERT(elementSize(type) == 1);
@@ -1890,7 +1890,7 @@
     // We would be loading this into base as in get_by_val, except that the slow
     // path expects the base to be unclobbered.
     loadPtr(Address(base, JSArrayBufferView::offsetOfVector()), lateScratch);
-    cageConditionally(Gigacage::Primitive, lateScratch, lateScratch2);
+    cageConditionally(Gigacage::Primitive, lateScratch, lateScratch2, lateScratch2);
     
     switch (elementSize(type)) {
     case 4:

Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm (246149 => 246150)


--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm	2019-06-06 11:34:10 UTC (rev 246149)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm	2019-06-06 13:20:56 UTC (rev 246150)
@@ -76,7 +76,7 @@
 #
 #  - pc holds the (native) program counter on 32-bits ARM architectures (ARMv7)
 #
-#  - t0, t1, t2, t3, t4 and optionally t5 are temporary registers that can get trashed on
+#  - t0, t1, t2, t3, t4, and optionally t5, t6, and t7 are temporary registers that can get trashed on
 #  calls, and are pairwise distinct registers. t4 holds the JS program counter, so use
 #  with caution in opcodes (actually, don't use it in opcodes at all, except as PC).
 #

Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm (246149 => 246150)


--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm	2019-06-06 11:34:10 UTC (rev 246149)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm	2019-06-06 13:20:56 UTC (rev 246150)
@@ -434,11 +434,20 @@
 
 macro loadCagedPrimitive(source, dest, scratchOrLength)
     loadp source, dest
-    if GIGACAGE_ENABLED
-        uncage(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr Gigacage::primitiveGigacageMask, dest, scratchOrLength)
-    elsif ARM64E
+    if ARM64E
+        const result = t7
         untagArrayPtr scratchOrLength, dest
+        move dest, result
+    else
+        const result = dest
     end
+    if GIGACAGE_ENABLED
+        uncage(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr Gigacage::primitiveGigacageMask, result, scratchOrLength)
+        if ARM64E
+            const numberOfPACBits = constexpr MacroAssembler::numberOfPACBits
+            bfiq result, 0, 64 - numberOfPACBits, dest
+        end
+    end
 end
 
 macro loadCagedJSValue(source, dest, scratchOrLength)

Modified: trunk/Source/_javascript_Core/offlineasm/arm64.rb (246149 => 246150)


--- trunk/Source/_javascript_Core/offlineasm/arm64.rb	2019-06-06 11:34:10 UTC (rev 246149)
+++ trunk/Source/_javascript_Core/offlineasm/arm64.rb	2019-06-06 13:20:56 UTC (rev 246150)
@@ -126,6 +126,8 @@
           arm64GPRName('x5', kind)
         when 't6'
           arm64GPRName('x6', kind)
+        when 't7'
+          arm64GPRName('x7', kind)
         when 'cfr'
             arm64GPRName('x29', kind)
         when 'csr0'
@@ -1019,6 +1021,8 @@
             $asm.puts "smaddl #{operands[2].arm64Operand(:quad)}, #{operands[0].arm64Operand(:word)}, #{operands[1].arm64Operand(:word)}, xzr"
         when "memfence"
             $asm.puts "dmb sy"
+        when "bfiq"
+            $asm.puts "bfi #{operands[3].arm64Operand(:quad)}, #{operands[0].arm64Operand(:quad)}, #{operands[1].value}, #{operands[2].value}"
         when "pcrtoaddr"
             $asm.puts "adr #{operands[1].arm64Operand(:quad)}, #{operands[0].value}"
         when "nopCortexA53Fix835769"

Modified: trunk/Source/_javascript_Core/offlineasm/instructions.rb (246149 => 246150)


--- trunk/Source/_javascript_Core/offlineasm/instructions.rb	2019-06-06 11:34:10 UTC (rev 246149)
+++ trunk/Source/_javascript_Core/offlineasm/instructions.rb	2019-06-06 13:20:56 UTC (rev 246150)
@@ -273,6 +273,7 @@
 
 ARM64_INSTRUCTIONS =
     [
+     "bfiq", # Bit field insert <source reg> <last bit written> <width immediate> <dest reg>
      "pcrtoaddr",   # Address from PC relative offset - adr instruction
      "nopFixCortexA53Err835769", # nop on Cortex-A53 (nothing otherwise)
      "globaladdr"

Modified: trunk/Source/_javascript_Core/offlineasm/registers.rb (246149 => 246150)


--- trunk/Source/_javascript_Core/offlineasm/registers.rb	2019-06-06 11:34:10 UTC (rev 246149)
+++ trunk/Source/_javascript_Core/offlineasm/registers.rb	2019-06-06 13:20:56 UTC (rev 246150)
@@ -32,6 +32,7 @@
      "t4",
      "t5",
      "t6",
+     "t7",
      "cfr",
      "a0",
      "a1",

Modified: trunk/Source/_javascript_Core/wasm/WasmAirIRGenerator.cpp (246149 => 246150)


--- trunk/Source/_javascript_Core/wasm/WasmAirIRGenerator.cpp	2019-06-06 11:34:10 UTC (rev 246149)
+++ trunk/Source/_javascript_Core/wasm/WasmAirIRGenerator.cpp	2019-06-06 13:20:56 UTC (rev 246150)
@@ -848,8 +848,7 @@
         patchpoint->numGPScratchRegisters = Gigacage::isEnabled(Gigacage::Primitive) ? 1 : 0;
 
         patchpoint->setGenerator([pinnedRegs] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) {
-            RELEASE_ASSERT(!Gigacage::isEnabled(Gigacage::Primitive) || !isARM64());
-            AllowMacroScratchRegisterUsageIf allowScratch(jit, !isARM64());
+            AllowMacroScratchRegisterUsage allowScratch(jit);
             GPRReg baseMemory = pinnedRegs->baseMemoryPointer;
             GPRReg scratchOrSize = Gigacage::isEnabled(Gigacage::Primitive) ? params.gpScratch(0) : pinnedRegs->sizeRegister;
 
@@ -856,7 +855,7 @@
             jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemorySize()), pinnedRegs->sizeRegister);
             jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemory()), baseMemory);
 
-            jit.cageConditionally(Gigacage::Primitive, baseMemory, scratchOrSize);
+            jit.cageConditionally(Gigacage::Primitive, baseMemory, pinnedRegs->sizeRegister, scratchOrSize);
         });
 
         emitPatchpoint(block, patchpoint, Tmp(), instance);
@@ -1988,7 +1987,7 @@
             jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemorySize()), pinnedRegs.sizeRegister); // Memory size.
             jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemory()), baseMemory); // Memory::void*.
 
-            jit.cageConditionally(Gigacage::Primitive, baseMemory, scratchOrSize);
+            jit.cageConditionally(Gigacage::Primitive, baseMemory, pinnedRegs.sizeRegister, scratchOrSize);
         });
 
         emitPatchpoint(doContextSwitch, patchpoint, Tmp(), newContextInstance, instanceValue());

Modified: trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp (246149 => 246150)


--- trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp	2019-06-06 11:34:10 UTC (rev 246149)
+++ trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp	2019-06-06 13:20:56 UTC (rev 246150)
@@ -491,8 +491,7 @@
 
         patchpoint->append(instance, ValueRep::SomeRegister);
         patchpoint->setGenerator([pinnedRegs] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) {
-            RELEASE_ASSERT(!Gigacage::isEnabled(Gigacage::Primitive) || !isARM64());
-            AllowMacroScratchRegisterUsageIf allowScratch(jit, !isARM64());
+            AllowMacroScratchRegisterUsage allowScratch(jit);
             GPRReg baseMemory = pinnedRegs->baseMemoryPointer;
             GPRReg scratchOrSize = Gigacage::isEnabled(Gigacage::Primitive) ? params.gpScratch(0) : pinnedRegs->sizeRegister;
 
@@ -499,7 +498,7 @@
             jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemorySize()), pinnedRegs->sizeRegister);
             jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemory()), baseMemory);
 
-            jit.cageConditionally(Gigacage::Primitive, baseMemory, scratchOrSize);
+            jit.cageConditionally(Gigacage::Primitive, baseMemory, pinnedRegs->sizeRegister, scratchOrSize);
         });
     }
 }
@@ -1401,7 +1400,7 @@
             jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemorySize()), pinnedRegs.sizeRegister); // Memory size.
             jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemory()), baseMemory); // Memory::void*.
 
-            jit.cageConditionally(Gigacage::Primitive, baseMemory, scratchOrSize);
+            jit.cageConditionally(Gigacage::Primitive, baseMemory, pinnedRegs.sizeRegister, scratchOrSize);
         });
         doContextSwitch->appendNewControlValue(m_proc, Jump, origin(), continuation);
 

Modified: trunk/Source/_javascript_Core/wasm/WasmBinding.cpp (246149 => 246150)


--- trunk/Source/_javascript_Core/wasm/WasmBinding.cpp	2019-06-06 11:34:10 UTC (rev 246149)
+++ trunk/Source/_javascript_Core/wasm/WasmBinding.cpp	2019-06-06 13:20:56 UTC (rev 246150)
@@ -67,11 +67,11 @@
     // FIXME the following code assumes that all Wasm::Instance have the same pinned registers. https://bugs.webkit.org/show_bug.cgi?id=162952
     // Set up the callee's baseMemory register as well as the memory size registers.
     {
-        GPRReg scratchOrSize = isARM64E() ? pinnedRegs.sizeRegister : wasmCallingConventionAir().prologueScratch(1);
+        GPRReg scratchOrSize = !Gigacage::isEnabled(Gigacage::Primitive) ? pinnedRegs.sizeRegister : wasmCallingConventionAir().prologueScratch(1);
 
         jit.loadPtr(JIT::Address(baseMemory, Wasm::Instance::offsetOfCachedMemorySize()), pinnedRegs.sizeRegister); // Memory size.
         jit.loadPtr(JIT::Address(baseMemory, Wasm::Instance::offsetOfCachedMemory()), baseMemory); // Wasm::Memory::TaggedArrayStoragePtr<void> (void*).
-        jit.cageConditionally(Gigacage::Primitive, baseMemory, scratchOrSize);
+        jit.cageConditionally(Gigacage::Primitive, baseMemory, pinnedRegs.sizeRegister, scratchOrSize);
     }
 
     // Tail call into the callee WebAssembly function.

Modified: trunk/Source/_javascript_Core/wasm/js/JSToWasm.cpp (246149 => 246150)


--- trunk/Source/_javascript_Core/wasm/js/JSToWasm.cpp	2019-06-06 11:34:10 UTC (rev 246149)
+++ trunk/Source/_javascript_Core/wasm/js/JSToWasm.cpp	2019-06-06 13:20:56 UTC (rev 246150)
@@ -228,7 +228,7 @@
         }
 
         jit.loadPtr(CCallHelpers::Address(currentInstanceGPR, Wasm::Instance::offsetOfCachedMemory()), baseMemory);
-        jit.cageConditionally(Gigacage::Primitive, baseMemory, scratchOrSize);
+        jit.cageConditionally(Gigacage::Primitive, baseMemory, scratchOrSize, scratchOrSize);
     }
 
     CCallHelpers::Call call = jit.threadSafePatchableNearCall();

Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunction.cpp (246149 => 246150)


--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunction.cpp	2019-06-06 11:34:10 UTC (rev 246149)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunction.cpp	2019-06-06 13:20:56 UTC (rev 246150)
@@ -423,7 +423,7 @@
         }
 
         jit.loadPtr(CCallHelpers::Address(scratchGPR, Wasm::Instance::offsetOfCachedMemory()), baseMemory);
-        jit.cageConditionally(Gigacage::Primitive, baseMemory, scratchOrSize);
+        jit.cageConditionally(Gigacage::Primitive, baseMemory, scratchOrSize, scratchOrSize);
     }
 
     // We use this callee to indicate how to unwind past these types of frames:

Modified: trunk/Source/bmalloc/ChangeLog (246149 => 246150)


--- trunk/Source/bmalloc/ChangeLog	2019-06-06 11:34:10 UTC (rev 246149)
+++ trunk/Source/bmalloc/ChangeLog	2019-06-06 13:20:56 UTC (rev 246150)
@@ -1,3 +1,12 @@
+2019-06-06  Keith Miller  <[email protected]>
+
+        Reenable Gigacage on ARM64.
+        https://bugs.webkit.org/show_bug.cgi?id=198453
+
+        Reviewed by Michael Saboff.
+
+        * bmalloc/Gigacage.h:
+
 2019-06-03  Commit Queue  <[email protected]>
 
         Unreviewed, rolling out r246022.

Modified: trunk/Source/bmalloc/bmalloc/Gigacage.h (246149 => 246150)


--- trunk/Source/bmalloc/bmalloc/Gigacage.h	2019-06-06 11:34:10 UTC (rev 246149)
+++ trunk/Source/bmalloc/bmalloc/Gigacage.h	2019-06-06 13:20:56 UTC (rev 246150)
@@ -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
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to