termux-packages/packages/swift/swift-compiler-move-tag.pat...

88 lines
4.3 KiB
Plaintext

diff --git a/swift/lib/IRGen/MetadataRequest.cpp b/swift/lib/IRGen/MetadataRequest.cpp
index 0a83d8bb6ec..57af3ee003a 100644
--- a/swift/lib/IRGen/MetadataRequest.cpp
+++ b/swift/lib/IRGen/MetadataRequest.cpp
@@ -2677,9 +2677,16 @@ emitMetadataAccessByMangledName(IRGenFunction &IGF, CanType type,
unsigned mangledStringSize;
std::tie(mangledString, mangledStringSize) =
IGM.getTypeRef(type, CanGenericSignature(), MangledTypeRefRole::Metadata);
-
- assert(mangledStringSize < 0x80000000u
- && "2GB of mangled name ought to be enough for anyone");
+
+ // Android AArch64 reserves the top byte of the address for memory tagging
+ // since Android 11, so only use the bottom 23 bits to store this size
+ // and the 24th bit to signal that there is a size.
+ if (IGM.Triple.isAndroid() && IGM.Triple.getArch() == llvm::Triple::aarch64)
+ assert(mangledStringSize < 0x00800001u &&
+ "8MB of mangled name ought to be enough for Android AArch64");
+ else
+ assert(mangledStringSize < 0x80000000u &&
+ "2GB of mangled name ought to be enough for anyone");
// Get or create the cache variable if necessary.
auto cache = IGM.getAddrOfTypeMetadataDemanglingCacheVariable(type,
@@ -2749,6 +2756,21 @@ emitMetadataAccessByMangledName(IRGenFunction &IGF, CanType type,
auto contBB = subIGF.createBasicBlock("");
llvm::Value *comparison = subIGF.Builder.CreateICmpSLT(load,
llvm::ConstantInt::get(IGM.Int64Ty, 0));
+
+ // Check if the 24th bit is set on Android AArch64 and only instantiate the
+ // type metadata if it is, as otherwise it might be negative only because
+ // of the memory tag on Android.
+ if (IGM.Triple.isAndroid() &&
+ IGM.Triple.getArch() == llvm::Triple::aarch64) {
+
+ auto getBitAfterAndroidTag = subIGF.Builder.CreateAnd(
+ load, llvm::ConstantInt::get(IGM.Int64Ty, 0x0080000000000000));
+ auto checkNotAndroidTag = subIGF.Builder.CreateICmpNE(
+ getBitAfterAndroidTag, llvm::ConstantInt::get(IGM.Int64Ty, 0));
+
+ comparison = subIGF.Builder.CreateAnd(comparison, checkNotAndroidTag);
+ }
+
comparison = subIGF.Builder.CreateExpect(comparison,
llvm::ConstantInt::get(IGM.Int1Ty, 0));
subIGF.Builder.CreateCondBr(comparison, isUnfilledBB, contBB);
diff --git a/swift/lib/IRGen/SwiftTargetInfo.cpp b/swift/lib/IRGen/SwiftTargetInfo.cpp
--- a/swift/lib/IRGen/SwiftTargetInfo.cpp
+++ b/swift/lib/IRGen/SwiftTargetInfo.cpp
@@ -36,8 +36,12 @@ static void setToMask(SpareBitVector &bits, unsigned size, uint64_t mask) {
/// Configures target-specific information for arm64 platforms.
static void configureARM64(IRGenModule &IGM, const llvm::Triple &triple,
SwiftTargetInfo &target) {
- setToMask(target.PointerSpareBits, 64,
- SWIFT_ABI_ARM64_SWIFT_SPARE_BITS_MASK);
+ if (triple.isAndroid())
+ setToMask(target.PointerSpareBits, 64,
+ SWIFT_ABI_ANDROID_ARM64_SWIFT_SPARE_BITS_MASK);
+ else
+ setToMask(target.PointerSpareBits, 64,
+ SWIFT_ABI_ARM64_SWIFT_SPARE_BITS_MASK);
setToMask(target.ObjCPointerReservedBits, 64,
SWIFT_ABI_ARM64_OBJC_RESERVED_BITS_MASK);
setToMask(target.IsObjCPointerBit, 64, SWIFT_ABI_ARM64_IS_OBJC_BIT);
diff --git a/swift/stdlib/public/SwiftShims/System.h b/swift/stdlib/public/SwiftShims/System.h
index 8fe54f6bda..a70acfd7be 100644
--- a/swift/stdlib/public/SwiftShims/System.h
+++ b/swift/stdlib/public/SwiftShims/System.h
@@ -152,10 +152,18 @@
/// Darwin reserves the low 4GB of address space.
#define SWIFT_ABI_DARWIN_ARM64_LEAST_VALID_POINTER 0x100000000ULL
+// Android AArch64 reserves the top byte for pointer tagging since Android 11,
+// so shift this tag to the second byte.
+#define SWIFT_ABI_ANDROID_ARM64_SWIFT_SPARE_BITS_MASK 0x00F0000000000007ULL
+
+#if defined(__ANDROID__) && defined(__aarch64__)
+#define SWIFT_ABI_ARM64_SWIFT_SPARE_BITS_MASK SWIFT_ABI_ANDROID_ARM64_SWIFT_SPARE_BITS_MASK
+#else
// TBI guarantees the top byte of pointers is unused, but ARMv8.5-A
// claims the bottom four bits of that for memory tagging.
// Heap objects are eight-byte aligned.
#define SWIFT_ABI_ARM64_SWIFT_SPARE_BITS_MASK 0xF000000000000007ULL
+#endif
// Objective-C reserves just the high bit for tagged pointers.
#define SWIFT_ABI_ARM64_OBJC_RESERVED_BITS_MASK 0x8000000000000000ULL