88 lines
4.3 KiB
Plaintext
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
|