Fix emitAllocateWithNonNullAllocator to work on arm
authorsbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 27 Jan 2018 00:05:16 +0000 (00:05 +0000)
committersbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 27 Jan 2018 00:05:16 +0000 (00:05 +0000)
https://bugs.webkit.org/show_bug.cgi?id=182187
<rdar://problem/36906550>

Reviewed by Filip Pizlo.

This patch unifies the x86 and ARM paths in emitAllocateWithNonNullAllocator
and makes it so that emitAllocateWithNonNullAllocator uses the macro scratch
register on ARM.

* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::allocateHeapCell):
* jit/AssemblyHelpers.cpp:
(JSC::AssemblyHelpers::emitAllocateWithNonNullAllocator):

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

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
Source/JavaScriptCore/jit/AssemblyHelpers.cpp

index ade7621..7cb604e 100644 (file)
@@ -1,3 +1,20 @@
+2018-01-26  Saam Barati  <sbarati@apple.com>
+
+        Fix emitAllocateWithNonNullAllocator to work on arm
+        https://bugs.webkit.org/show_bug.cgi?id=182187
+        <rdar://problem/36906550>
+
+        Reviewed by Filip Pizlo.
+
+        This patch unifies the x86 and ARM paths in emitAllocateWithNonNullAllocator
+        and makes it so that emitAllocateWithNonNullAllocator uses the macro scratch
+        register on ARM.
+
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::allocateHeapCell):
+        * jit/AssemblyHelpers.cpp:
+        (JSC::AssemblyHelpers::emitAllocateWithNonNullAllocator):
+
 2018-01-26  Joseph Pecoraro  <pecoraro@apple.com>
 
         Rebaselining builtin generator tests after r227685.
index d7f4b87..2460a4d 100644 (file)
@@ -31,6 +31,7 @@
 #include "AirCode.h"
 #include "AirGenerationContext.h"
 #include "AllowMacroScratchRegisterUsage.h"
+#include "AllowMacroScratchRegisterUsageIf.h"
 #include "AtomicsObject.h"
 #include "B3CheckValue.h"
 #include "B3FenceValue.h"
@@ -12016,6 +12017,10 @@ private:
         LBasicBlock lastNext = m_out.insertNewBlocksBefore(continuation);
         
         PatchpointValue* patchpoint = m_out.patchpoint(pointerType());
+        if (isARM64()) {
+            // emitAllocateWithNonNullAllocator uses the scratch registers on ARM.
+            patchpoint->clobber(RegisterSet::macroScratchRegisters());
+        }
         patchpoint->effects.terminal = true;
         if (actualAllocator.isConstant())
             patchpoint->numGPScratchRegisters++;
@@ -12029,6 +12034,7 @@ private:
         
         patchpoint->setGenerator(
             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
+                AllowMacroScratchRegisterUsageIf allowScratchIf(jit, isARM64());
                 CCallHelpers::JumpList jumpToSlowPath;
                 
                 GPRReg allocatorGPR;
index cea5a72..93df154 100644 (file)
@@ -584,14 +584,16 @@ void AssemblyHelpers::emitRandomThunk(VM& vm, GPRReg scratch0, GPRReg scratch1,
 
 void AssemblyHelpers::emitAllocateWithNonNullAllocator(GPRReg resultGPR, const JITAllocator& allocator, GPRReg allocatorGPR, GPRReg scratchGPR, JumpList& slowPath)
 {
-    // NOTE: This is carefully written so that we can call it while we disallow scratch
-    // register usage.
-        
     if (Options::forceGCSlowPaths()) {
         slowPath.append(jump());
         return;
     }
-    
+
+    // NOTE, some invariants of this function:
+    // - When going to the slow path, we must leave resultGPR with zero in it.
+    // - We *can not* use RegisterSet::macroScratchRegisters on x86.
+    // - We *can* use RegisterSet::macroScratchRegisters on ARM.
+
     Jump popPath;
     Jump done;
     
@@ -600,19 +602,11 @@ void AssemblyHelpers::emitAllocateWithNonNullAllocator(GPRReg resultGPR, const J
 #else
     loadPtr(&vm().threadLocalCacheData, scratchGPR);
 #endif
-    if (!isX86())
-        load32(Address(scratchGPR, ThreadLocalCache::offsetOfSizeInData()), resultGPR);
     if (allocator.isConstant()) {
-        if (isX86())
-            slowPath.append(branch32(BelowOrEqual, Address(scratchGPR, ThreadLocalCache::offsetOfSizeInData()), TrustedImm32(allocator.allocator().offset())));
-        else
-            slowPath.append(branch32(BelowOrEqual, resultGPR, TrustedImm32(allocator.allocator().offset())));
+        slowPath.append(branch32(BelowOrEqual, Address(scratchGPR, ThreadLocalCache::offsetOfSizeInData()), TrustedImm32(allocator.allocator().offset())));
         addPtr(TrustedImm32(ThreadLocalCache::offsetOfFirstAllocatorInData() + allocator.allocator().offset()), scratchGPR, allocatorGPR);
     } else {
-        if (isX86())
-            slowPath.append(branch32(BelowOrEqual, Address(scratchGPR, ThreadLocalCache::offsetOfSizeInData()), allocatorGPR));
-        else
-            slowPath.append(branch32(BelowOrEqual, resultGPR, allocatorGPR));
+        slowPath.append(branch32(BelowOrEqual, Address(scratchGPR, ThreadLocalCache::offsetOfSizeInData()), allocatorGPR));
         addPtr(TrustedImm32(ThreadLocalCache::offsetOfFirstAllocatorInData()), allocatorGPR);
         addPtr(scratchGPR, allocatorGPR);
     }
@@ -622,35 +616,20 @@ void AssemblyHelpers::emitAllocateWithNonNullAllocator(GPRReg resultGPR, const J
     if (allocator.isConstant())
         add32(TrustedImm32(-allocator.allocator().cellSize(vm().heap)), resultGPR, scratchGPR);
     else {
-        if (isX86()) {
-            move(resultGPR, scratchGPR);
-            sub32(Address(allocatorGPR, LocalAllocator::offsetOfCellSize()), scratchGPR);
-        } else {
-            load32(Address(allocatorGPR, LocalAllocator::offsetOfCellSize()), scratchGPR);
-            sub32(resultGPR, scratchGPR, scratchGPR);
-        }
+        move(resultGPR, scratchGPR);
+        sub32(Address(allocatorGPR, LocalAllocator::offsetOfCellSize()), scratchGPR);
     }
     negPtr(resultGPR);
     store32(scratchGPR, Address(allocatorGPR, LocalAllocator::offsetOfFreeList() + FreeList::offsetOfRemaining()));
     Address payloadEndAddr = Address(allocatorGPR, LocalAllocator::offsetOfFreeList() + FreeList::offsetOfPayloadEnd());
-    if (isX86())
-        addPtr(payloadEndAddr, resultGPR);
-    else {
-        loadPtr(payloadEndAddr, scratchGPR);
-        addPtr(scratchGPR, resultGPR);
-    }
-        
+    addPtr(payloadEndAddr, resultGPR);
+
     done = jump();
         
     popPath.link(this);
         
     loadPtr(Address(allocatorGPR, LocalAllocator::offsetOfFreeList() + FreeList::offsetOfScrambledHead()), resultGPR);
-    if (isX86())
-        xorPtr(Address(allocatorGPR, LocalAllocator::offsetOfFreeList() + FreeList::offsetOfSecret()), resultGPR);
-    else {
-        loadPtr(Address(allocatorGPR, LocalAllocator::offsetOfFreeList() + FreeList::offsetOfSecret()), scratchGPR);
-        xorPtr(scratchGPR, resultGPR);
-    }
+    xorPtr(Address(allocatorGPR, LocalAllocator::offsetOfFreeList() + FreeList::offsetOfSecret()), resultGPR);
     slowPath.append(branchTestPtr(Zero, resultGPR));
         
     // The object is half-allocated: we have what we know is a fresh object, but