swift: fix memory tagging collisions on aarch64 since Android 11
This commit is contained in:
parent
10fafcb645
commit
5d98fde4ab
@ -3,6 +3,7 @@ TERMUX_PKG_DESCRIPTION="Swift is a high-performance system programming language"
|
||||
TERMUX_PKG_LICENSE="Apache-2.0, NCSA"
|
||||
TERMUX_PKG_MAINTAINER="@buttaface"
|
||||
TERMUX_PKG_VERSION=5.5.2
|
||||
TERMUX_PKG_REVISION=1
|
||||
SWIFT_RELEASE="RELEASE"
|
||||
TERMUX_PKG_SRCURL=https://github.com/apple/swift/archive/swift-$TERMUX_PKG_VERSION-$SWIFT_RELEASE.tar.gz
|
||||
TERMUX_PKG_SHA256=0046ecab640475441251b1cceb3dd167a4c7729852104d7675bdbd75fced6b82
|
||||
@ -25,7 +26,7 @@ SWIFT_BUILD_FLAGS="$SWIFT_TOOLCHAIN_FLAGS $SWIFT_PATH_FLAGS"
|
||||
|
||||
if [ "$TERMUX_ON_DEVICE_BUILD" = "false" ]; then
|
||||
SWIFT_BIN="swift-$TERMUX_PKG_VERSION-$SWIFT_RELEASE-ubuntu20.04"
|
||||
SWIFT_BINDIR="$TERMUX_PKG_HOSTBUILD_DIR/$SWIFT_BIN/usr/bin"
|
||||
export SWIFT_BINDIR="$TERMUX_PKG_HOSTBUILD_DIR/$SWIFT_BIN/usr/bin"
|
||||
fi
|
||||
SWIFT_ARCH=$TERMUX_ARCH
|
||||
test $SWIFT_ARCH == 'arm' && SWIFT_ARCH='armv7'
|
||||
@ -104,17 +105,26 @@ termux_step_host_build() {
|
||||
# The Ubuntu CI may not have clang/clang++ in its path so explicitly set it
|
||||
# to clang-10 instead.
|
||||
if [ -z "$CLANG" ]; then
|
||||
CLANG=$(command -v clang-10)
|
||||
CLANGXX=$(command -v clang++-10)
|
||||
CLANG=$(command -v clang-12)
|
||||
CLANGXX=$(command -v clang++-12)
|
||||
fi
|
||||
|
||||
local SKIP_BUILD="--skip-build-compiler-rt"
|
||||
test $TERMUX_ARCH != 'aarch64' && SKIP_BUILD="--skip-build-cmark --skip-build-llvm --skip-build-swift"
|
||||
|
||||
# Natively compile llvm-tblgen and some other files needed later.
|
||||
SWIFT_BUILD_ROOT=$TERMUX_PKG_HOSTBUILD_DIR $TERMUX_PKG_SRCDIR/swift/utils/build-script \
|
||||
-R --no-assertions -j $TERMUX_MAKE_PROCESSES $SWIFT_PATH_FLAGS \
|
||||
--skip-build-cmark --skip-build-llvm --skip-build-swift --build-toolchain-only \
|
||||
$SKIP_BUILD --build-toolchain-only \
|
||||
--host-cc=$CLANG --host-cxx=$CLANGXX
|
||||
|
||||
tar xf $TERMUX_PKG_CACHEDIR/$SWIFT_BIN.tar.gz -C $TERMUX_PKG_HOSTBUILD_DIR
|
||||
if [ "$TERMUX_ARCH" == "aarch64" ]; then
|
||||
rm $TERMUX_PKG_HOSTBUILD_DIR/swift-linux-x86_64/lib/swift/FrameworkABIBaseline
|
||||
cp -r $SWIFT_BIN/usr/lib/swift $TERMUX_PKG_HOSTBUILD_DIR/swift-linux-x86_64/lib
|
||||
ln -sf $SWIFT_BINDIR/../lib/clang/10.0.0 $TERMUX_PKG_HOSTBUILD_DIR/swift-linux-x86_64/lib/swift/clang
|
||||
patchelf --set-rpath \$ORIGIN $TERMUX_PKG_HOSTBUILD_DIR/swift-linux-x86_64/lib/swift/linux/libicu{uc,i18n}swift.so.65.1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
@ -143,6 +153,14 @@ termux_step_make() {
|
||||
|
||||
if [ "$TERMUX_ON_DEVICE_BUILD" = "false" ]; then
|
||||
ln -sf $TERMUX_PKG_HOSTBUILD_DIR/llvm-linux-x86_64 $TERMUX_PKG_BUILDDIR/llvm-linux-x86_64
|
||||
|
||||
local SWIFT_TOOLCHAIN=
|
||||
if [ "$SWIFT_ARCH" = "aarch64" ]; then
|
||||
ln -sf $TERMUX_PKG_HOSTBUILD_DIR/swift-linux-x86_64 $TERMUX_PKG_BUILDDIR/swift-linux-x86_64
|
||||
else
|
||||
SWIFT_TOOLCHAIN="--native-swift-tools-path=$SWIFT_BINDIR"
|
||||
fi
|
||||
|
||||
SWIFT_BUILD_FLAGS="$SWIFT_BUILD_FLAGS --android
|
||||
--android-ndk $TERMUX_STANDALONE_TOOLCHAIN --android-arch $SWIFT_ARCH
|
||||
--android-icu-uc $TERMUX_PREFIX/lib/libicuuc.so
|
||||
@ -153,7 +171,7 @@ termux_step_make() {
|
||||
--skip-local-build --skip-local-host-install
|
||||
--cross-compile-hosts=android-$SWIFT_ARCH
|
||||
--cross-compile-deps-path=$(dirname $TERMUX_PREFIX)
|
||||
--native-swift-tools-path=$SWIFT_BINDIR
|
||||
$SWIFT_TOOLCHAIN
|
||||
--native-clang-tools-path=$SWIFT_BINDIR"
|
||||
fi
|
||||
|
||||
|
87
packages/swift/swift-compiler-move-tag.patch.beforehostbuild
Normal file
87
packages/swift/swift-compiler-move-tag.patch.beforehostbuild
Normal file
@ -0,0 +1,87 @@
|
||||
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
|
306
packages/swift/swift-stdlib-move-tag.patch
Normal file
306
packages/swift/swift-stdlib-move-tag.patch
Normal file
@ -0,0 +1,306 @@
|
||||
diff --git a/swift/stdlib/public/SwiftShims/HeapObject.h b/swift/stdlib/public/SwiftShims/HeapObject.h
|
||||
index 5e165fd3d4..978f1b2293 100644
|
||||
--- a/swift/stdlib/public/SwiftShims/HeapObject.h
|
||||
+++ b/swift/stdlib/public/SwiftShims/HeapObject.h
|
||||
@@ -161,8 +161,13 @@ static_assert(alignof(HeapObject) == alignof(void*),
|
||||
(__swift_uintptr_t) SWIFT_ABI_ARM64_OBJC_RESERVED_BITS_MASK
|
||||
#define _swift_abi_ObjCReservedLowBits \
|
||||
(unsigned) SWIFT_ABI_ARM64_OBJC_NUM_RESERVED_LOW_BITS
|
||||
+#if defined(__ANDROID__)
|
||||
+#define _swift_BridgeObject_TaggedPointerBits \
|
||||
+ (__swift_uintptr_t) SWIFT_ABI_DEFAULT_BRIDGEOBJECT_TAG_64 >> 8
|
||||
+#else
|
||||
#define _swift_BridgeObject_TaggedPointerBits \
|
||||
(__swift_uintptr_t) SWIFT_ABI_DEFAULT_BRIDGEOBJECT_TAG_64
|
||||
+#endif
|
||||
|
||||
#elif defined(__powerpc64__)
|
||||
|
||||
diff --git a/swift/stdlib/public/core/Builtin.swift b/swift/stdlib/public/core/Builtin.swift
|
||||
index 8a7bb33243..65be72766e 100644
|
||||
--- a/swift/stdlib/public/core/Builtin.swift
|
||||
+++ b/swift/stdlib/public/core/Builtin.swift
|
||||
@@ -397,7 +397,13 @@ internal var _objectPointerIsObjCBit: UInt {
|
||||
#else
|
||||
@inlinable
|
||||
internal var _objectPointerIsObjCBit: UInt {
|
||||
- @inline(__always) get { return 0x4000_0000_0000_0000 }
|
||||
+ @inline(__always) get {
|
||||
+#if os(Android) && arch(arm64)
|
||||
+ return 0x0040_0000_0000_0000
|
||||
+#else
|
||||
+ return 0x4000_0000_0000_0000
|
||||
+#endif
|
||||
+ }
|
||||
}
|
||||
#endif
|
||||
|
||||
diff --git a/swift/stdlib/public/core/KeyPath.swift b/swift/stdlib/public/core/KeyPath.swift
|
||||
index 2d8f039742..3501f31c83 100644
|
||||
--- a/swift/stdlib/public/core/KeyPath.swift
|
||||
+++ b/swift/stdlib/public/core/KeyPath.swift
|
||||
@@ -1764,7 +1764,12 @@ internal struct KeyPathBuffer {
|
||||
internal mutating func pushRaw(size: Int, alignment: Int)
|
||||
-> UnsafeMutableRawBufferPointer {
|
||||
var baseAddress = buffer.baseAddress.unsafelyUnwrapped
|
||||
+#if os(Android) && arch(arm64)
|
||||
+ // Android AArch64 may tag the first byte so remove it before checking alignment.
|
||||
+ var misalign = (0x00FF_FFFF_FFFF_FFFF & Int(bitPattern: baseAddress)) % alignment
|
||||
+#else
|
||||
var misalign = Int(bitPattern: baseAddress) % alignment
|
||||
+#endif
|
||||
if misalign != 0 {
|
||||
misalign = alignment - misalign
|
||||
baseAddress = baseAddress.advanced(by: misalign)
|
||||
@@ -3242,7 +3247,12 @@ internal struct InstantiateKeyPathBuffer: KeyPathPatternVisitor {
|
||||
) {
|
||||
let alignment = MemoryLayout<T>.alignment
|
||||
var baseAddress = destData.baseAddress.unsafelyUnwrapped
|
||||
+#if os(Android) && arch(arm64)
|
||||
+ // Android AArch64 may tag the first byte so remove it before checking alignment.
|
||||
+ var misalign = (0x00FF_FFFF_FFFF_FFFF & Int(bitPattern: baseAddress)) % alignment
|
||||
+#else
|
||||
var misalign = Int(bitPattern: baseAddress) % alignment
|
||||
+#endif
|
||||
if misalign != 0 {
|
||||
misalign = alignment - misalign
|
||||
baseAddress = baseAddress.advanced(by: misalign)
|
||||
diff --git a/swift/stdlib/public/core/SmallString.swift b/swift/stdlib/public/core/SmallString.swift
|
||||
index df46b4e8bf..ac0969b570 100644
|
||||
--- a/swift/stdlib/public/core/SmallString.swift
|
||||
+++ b/swift/stdlib/public/core/SmallString.swift
|
||||
@@ -23,6 +23,9 @@
|
||||
// ↑ ↑
|
||||
// first (leftmost) code unit discriminator (incl. count)
|
||||
//
|
||||
+// On Android AArch64, there is one less byte available because the discriminator
|
||||
+// is stored in the penultimate code unit instead, to match where it's stored
|
||||
+// for large strings.
|
||||
@frozen @usableFromInline
|
||||
internal struct _SmallString {
|
||||
@usableFromInline
|
||||
@@ -78,6 +81,8 @@ extension _SmallString {
|
||||
internal static var capacity: Int {
|
||||
#if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32)
|
||||
return 10
|
||||
+#elseif os(Android) && arch(arm64)
|
||||
+ return 14
|
||||
#else
|
||||
return 15
|
||||
#endif
|
||||
@@ -111,7 +116,11 @@ extension _SmallString {
|
||||
// usage: it always clears the discriminator and count (in case it's full)
|
||||
@inlinable @inline(__always)
|
||||
internal var zeroTerminatedRawCodeUnits: RawBitPattern {
|
||||
+#if os(Android) && arch(arm64)
|
||||
+ let smallStringCodeUnitMask = ~UInt64(0xFFFF).bigEndian // zero last two bytes
|
||||
+#else
|
||||
let smallStringCodeUnitMask = ~UInt64(0xFF).bigEndian // zero last byte
|
||||
+#endif
|
||||
return (self._storage.0, self._storage.1 & smallStringCodeUnitMask)
|
||||
}
|
||||
|
||||
diff --git a/swift/stdlib/public/core/StringObject.swift b/swift/stdlib/public/core/StringObject.swift
|
||||
index b087e87f51..93f243ddd9 100644
|
||||
--- a/swift/stdlib/public/core/StringObject.swift
|
||||
+++ b/swift/stdlib/public/core/StringObject.swift
|
||||
@@ -56,6 +56,11 @@
|
||||
can compile to a fused check-and-branch, even if that burns part of the
|
||||
encoding space.
|
||||
|
||||
+ On Android AArch64, we cannot use the top byte for large strings because it is
|
||||
+ reserved by the OS for memory tagging since Android 11, so shift the
|
||||
+ discriminator to the second byte instead. This burns one more byte on small
|
||||
+ strings.
|
||||
+
|
||||
On 32-bit platforms, we store an explicit discriminator (as a UInt8) with the
|
||||
same encoding as above, placed in the high bits. E.g. `b62` above is in
|
||||
`_discriminator`'s `b6`.
|
||||
@@ -111,8 +116,13 @@ internal struct _StringObject {
|
||||
|
||||
@inlinable @inline(__always)
|
||||
init(count: Int, variant: Variant, discriminator: UInt64, flags: UInt16) {
|
||||
+#if os(Android) && arch(arm64)
|
||||
+ _internalInvariant(discriminator & 0x00FF_0000_0000_0000 == discriminator,
|
||||
+ "only the second byte can carry the discriminator and small count on Android AArch64")
|
||||
+#else
|
||||
_internalInvariant(discriminator & 0xFF00_0000_0000_0000 == discriminator,
|
||||
"only the top byte can carry the discriminator and small count")
|
||||
+#endif
|
||||
|
||||
self._count = count
|
||||
self._variant = variant
|
||||
@@ -349,7 +359,13 @@ extension _StringObject.Nibbles {
|
||||
extension _StringObject.Nibbles {
|
||||
// Mask for address bits, i.e. non-discriminator and non-extra high bits
|
||||
@inlinable @inline(__always)
|
||||
- static internal var largeAddressMask: UInt64 { return 0x0FFF_FFFF_FFFF_FFFF }
|
||||
+ static internal var largeAddressMask: UInt64 {
|
||||
+#if os(Android) && arch(arm64)
|
||||
+ return 0xFF0F_FFFF_FFFF_FFFF
|
||||
+#else
|
||||
+ return 0x0FFF_FFFF_FFFF_FFFF
|
||||
+#endif
|
||||
+ }
|
||||
|
||||
// Mask for address bits, i.e. non-discriminator and non-extra high bits
|
||||
@inlinable @inline(__always)
|
||||
@@ -360,20 +376,32 @@ extension _StringObject.Nibbles {
|
||||
// Discriminator for small strings
|
||||
@inlinable @inline(__always)
|
||||
internal static func small(isASCII: Bool) -> UInt64 {
|
||||
+#if os(Android) && arch(arm64)
|
||||
+ return isASCII ? 0x00E0_0000_0000_0000 : 0x00A0_0000_0000_0000
|
||||
+#else
|
||||
return isASCII ? 0xE000_0000_0000_0000 : 0xA000_0000_0000_0000
|
||||
+#endif
|
||||
}
|
||||
|
||||
// Discriminator for small strings
|
||||
@inlinable @inline(__always)
|
||||
internal static func small(withCount count: Int, isASCII: Bool) -> UInt64 {
|
||||
_internalInvariant(count <= _SmallString.capacity)
|
||||
+#if os(Android) && arch(arm64)
|
||||
+ return small(isASCII: isASCII) | UInt64(truncatingIfNeeded: count) &<< 48
|
||||
+#else
|
||||
return small(isASCII: isASCII) | UInt64(truncatingIfNeeded: count) &<< 56
|
||||
+#endif
|
||||
}
|
||||
|
||||
// Discriminator for large, immortal, swift-native strings
|
||||
@inlinable @inline(__always)
|
||||
internal static func largeImmortal() -> UInt64 {
|
||||
+#if os(Android) && arch(arm64)
|
||||
+ return 0x0080_0000_0000_0000
|
||||
+#else
|
||||
return 0x8000_0000_0000_0000
|
||||
+#endif
|
||||
}
|
||||
|
||||
// Discriminator for large, mortal (i.e. managed), swift-native strings
|
||||
@@ -381,7 +409,11 @@ extension _StringObject.Nibbles {
|
||||
internal static func largeMortal() -> UInt64 { return 0x0000_0000_0000_0000 }
|
||||
|
||||
internal static func largeCocoa(providesFastUTF8: Bool) -> UInt64 {
|
||||
+#if os(Android) && arch(arm64)
|
||||
+ return providesFastUTF8 ? 0x0040_0000_0000_0000 : 0x0050_0000_0000_0000
|
||||
+#else
|
||||
return providesFastUTF8 ? 0x4000_0000_0000_0000 : 0x5000_0000_0000_0000
|
||||
+#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,7 +429,11 @@ extension _StringObject {
|
||||
|
||||
@inlinable @inline(__always)
|
||||
internal var isImmortal: Bool {
|
||||
+#if os(Android) && arch(arm64)
|
||||
+ return (discriminatedObjectRawBits & 0x0080_0000_0000_0000) != 0
|
||||
+#else
|
||||
return (discriminatedObjectRawBits & 0x8000_0000_0000_0000) != 0
|
||||
+#endif
|
||||
}
|
||||
|
||||
@inlinable @inline(__always)
|
||||
@@ -405,7 +441,11 @@ extension _StringObject {
|
||||
|
||||
@inlinable @inline(__always)
|
||||
internal var isSmall: Bool {
|
||||
+#if os(Android) && arch(arm64)
|
||||
+ return (discriminatedObjectRawBits & 0x0020_0000_0000_0000) != 0
|
||||
+#else
|
||||
return (discriminatedObjectRawBits & 0x2000_0000_0000_0000) != 0
|
||||
+#endif
|
||||
}
|
||||
|
||||
@inlinable @inline(__always)
|
||||
@@ -419,7 +459,11 @@ extension _StringObject {
|
||||
// - Non-Cocoa shared strings
|
||||
@inlinable @inline(__always)
|
||||
internal var providesFastUTF8: Bool {
|
||||
+#if os(Android) && arch(arm64)
|
||||
+ return (discriminatedObjectRawBits & 0x0010_0000_0000_0000) == 0
|
||||
+#else
|
||||
return (discriminatedObjectRawBits & 0x1000_0000_0000_0000) == 0
|
||||
+#endif
|
||||
}
|
||||
|
||||
@inlinable @inline(__always)
|
||||
@@ -429,16 +473,26 @@ extension _StringObject {
|
||||
// conforms to `_AbstractStringStorage`
|
||||
@inline(__always)
|
||||
internal var hasStorage: Bool {
|
||||
+#if os(Android) && arch(arm64)
|
||||
+ return (discriminatedObjectRawBits & 0x00F0_0000_0000_0000) == 0
|
||||
+#else
|
||||
return (discriminatedObjectRawBits & 0xF000_0000_0000_0000) == 0
|
||||
+#endif
|
||||
}
|
||||
|
||||
// Whether we are a mortal, native (tail-allocated) string
|
||||
@inline(__always)
|
||||
internal var hasNativeStorage: Bool {
|
||||
+#if os(Android) && arch(arm64)
|
||||
+ // Android uses the same logic as explained below for other platforms,
|
||||
+ // except isSmall is at b53, so shift it to b61 first before proceeding.
|
||||
+ let bits = ~(discriminatedObjectRawBits << 8) & self._countAndFlagsBits
|
||||
+#else
|
||||
// b61 on the object means isSmall, and on countAndFlags means
|
||||
// isNativelyStored. We just need to check that b61 is 0 on the object and 1
|
||||
// on countAndFlags.
|
||||
let bits = ~discriminatedObjectRawBits & self._countAndFlagsBits
|
||||
+#endif
|
||||
let result = bits & 0x2000_0000_0000_0000 != 0
|
||||
_internalInvariant(!result || hasStorage, "native storage needs storage")
|
||||
return result
|
||||
@@ -466,7 +520,11 @@ extension _StringObject {
|
||||
@inline(__always)
|
||||
internal var largeIsCocoa: Bool {
|
||||
_internalInvariant(isLarge)
|
||||
+#if os(Android) && arch(arm64)
|
||||
+ return (discriminatedObjectRawBits & 0x0040_0000_0000_0000) != 0
|
||||
+#else
|
||||
return (discriminatedObjectRawBits & 0x4000_0000_0000_0000) != 0
|
||||
+#endif
|
||||
}
|
||||
|
||||
// Whether this string is in one of our fastest representations:
|
||||
@@ -535,7 +593,11 @@ extension _StringObject {
|
||||
|
||||
@inlinable
|
||||
internal static func getSmallCount(fromRaw x: UInt64) -> Int {
|
||||
+#if os(Android) && arch(arm64)
|
||||
+ return Int(truncatingIfNeeded: (x & 0x000F_0000_0000_0000) &>> 48)
|
||||
+#else
|
||||
return Int(truncatingIfNeeded: (x & 0x0F00_0000_0000_0000) &>> 56)
|
||||
+#endif
|
||||
}
|
||||
|
||||
@inlinable @inline(__always)
|
||||
@@ -546,7 +608,11 @@ extension _StringObject {
|
||||
|
||||
@inlinable
|
||||
internal static func getSmallIsASCII(fromRaw x: UInt64) -> Bool {
|
||||
+#if os(Android) && arch(arm64)
|
||||
+ return x & 0x0040_0000_0000_0000 != 0
|
||||
+#else
|
||||
return x & 0x4000_0000_0000_0000 != 0
|
||||
+#endif
|
||||
}
|
||||
@inlinable @inline(__always)
|
||||
internal var smallIsASCII: Bool {
|
||||
diff --git a/swift/stdlib/public/runtime/HeapObject.cpp b/swift/stdlib/public/runtime/HeapObject.cpp
|
||||
index 0a27620622..69b4350f7d 100644
|
||||
--- a/swift/stdlib/public/runtime/HeapObject.cpp
|
||||
+++ b/swift/stdlib/public/runtime/HeapObject.cpp
|
||||
@@ -66,6 +66,10 @@ static inline bool isValidPointerForNativeRetain(const void *p) {
|
||||
// arm64_32 is special since it has 32-bit pointers but __arm64__ is true.
|
||||
// Catch it early since __POINTER_WIDTH__ is generally non-portable.
|
||||
return p != nullptr;
|
||||
+#elif defined(__ANDROID__) && defined(__aarch64__)
|
||||
+ // Check the top of the second byte instead, since Android AArch64 reserves
|
||||
+ // the top byte for its own pointer tagging since Android 11.
|
||||
+ return (intptr_t)p << 8 > 0;
|
||||
#elif defined(__x86_64__) || defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64) || defined(__s390x__) || (defined(__powerpc64__) && defined(__LITTLE_ENDIAN__))
|
||||
// On these platforms, except s390x, the upper half of address space is reserved for the
|
||||
// kernel, so we can assume that pointer values in this range are invalid.
|
@ -2,12 +2,12 @@ diff --git a/swift/utils/swift_build_support/swift_build_support/products/produc
|
||||
index 741353f15ce..e54e211b705 100644
|
||||
--- a/swift/utils/swift_build_support/swift_build_support/products/product.py
|
||||
+++ b/swift/utils/swift_build_support/swift_build_support/products/product.py
|
||||
@@ -204,8 +204,6 @@ class Product(object):
|
||||
build_root = os.path.dirname(self.build_dir)
|
||||
@@ -202,7 +202,7 @@
|
||||
install_destdir = '%s/intermediate-install/%s' % (build_root,
|
||||
host_target)
|
||||
- else:
|
||||
else:
|
||||
- install_destdir = os.path.join(install_destdir, self.args.host_target)
|
||||
+ return os.path.join(os.path.dirname(self.build_dir), "swift-%s" % self.args.host_target)
|
||||
return targets.toolchain_path(install_destdir,
|
||||
self.args.install_prefix)
|
||||
|
||||
|
@ -0,0 +1,97 @@
|
||||
diff --git a/sourcekit-lsp/Utilities/build-script-helper.py b/sourcekit-lsp/Utilities/build-script-helper.py
|
||||
--- a/sourcekit-lsp/Utilities/build-script-helper.py
|
||||
+++ b/sourcekit-lsp/Utilities/build-script-helper.py
|
||||
@@ -93,6 +93,10 @@
|
||||
|
||||
def handle_invocation(swift_exec, args):
|
||||
swiftpm_args = get_swiftpm_options(args)
|
||||
+ if args.cross_compile_host and re.match('android-aarch64', args.cross_compile_host):
|
||||
+ swiftpm_exec = os.path.join(os.path.realpath(os.getenv("SWIFT_BINDIR")), "swift")
|
||||
+ else:
|
||||
+ swiftpm_exec = swift_exec
|
||||
|
||||
env = os.environ
|
||||
# Set the toolchain used in tests at runtime
|
||||
@@ -120,7 +124,7 @@
|
||||
env['SWIFT_EXEC'] = '%sc' % (swift_exec)
|
||||
|
||||
if args.action == 'build':
|
||||
- swiftpm('build', swift_exec, swiftpm_args, env)
|
||||
+ swiftpm('build', swiftpm_exec, swiftpm_args, env)
|
||||
elif args.action == 'test':
|
||||
if not args.skip_long_tests:
|
||||
env['SOURCEKIT_LSP_ENABLE_LONG_TESTS'] = '1'
|
||||
@@ -135,9 +139,9 @@
|
||||
test_args += ['--parallel']
|
||||
swiftpm('test', swift_exec, test_args, env)
|
||||
elif args.action == 'install':
|
||||
- bin_path = swiftpm_bin_path(swift_exec, swiftpm_args, env)
|
||||
+ bin_path = swiftpm_bin_path(swiftpm_exec, swiftpm_args, env)
|
||||
swiftpm_args += ['-Xswiftc', '-no-toolchain-stdlib-rpath']
|
||||
- swiftpm('build', swift_exec, swiftpm_args, env)
|
||||
+ swiftpm('build', swiftpm_exec, swiftpm_args, env)
|
||||
install(bin_path, args.install_prefixes if not None else [args.toolchain], args.toolchain)
|
||||
else:
|
||||
assert False, 'unknown action \'{}\''.format(args.action)
|
||||
diff --git a/swift-driver/Utilities/build-script-helper.py b/swift-driver/Utilities/build-script-helper.py
|
||||
--- a/swift-driver/Utilities/build-script-helper.py
|
||||
+++ b/swift-driver/Utilities/build-script-helper.py
|
||||
@@ -166,6 +167,10 @@
|
||||
toolchain_bin = os.path.join(args.toolchain, 'bin')
|
||||
swift_exec = os.path.join(toolchain_bin, 'swift')
|
||||
swiftc_exec = os.path.join(toolchain_bin, 'swiftc')
|
||||
+ if args.cross_compile_hosts and re.match('android-aarch64', args.cross_compile_hosts[0]):
|
||||
+ swiftpm_exec = os.path.join(os.path.realpath(os.getenv("SWIFT_BINDIR")), "swift")
|
||||
+ else:
|
||||
+ swiftpm_exec = swift_exec
|
||||
|
||||
# Platform-specific targets for which we must build swift-driver
|
||||
if args.cross_compile_hosts:
|
||||
@@ -190,7 +194,7 @@
|
||||
|
||||
if args.action == 'build':
|
||||
if args.cross_compile_hosts and not re.match('-macosx', args.cross_compile_hosts[0]):
|
||||
- swiftpm('build', swift_exec, swiftpm_args, env)
|
||||
+ swiftpm('build', swiftpm_exec, swiftpm_args, env)
|
||||
else:
|
||||
build_using_cmake(args, toolchain_bin, args.build_path, targets)
|
||||
|
||||
@@ -216,8 +220,8 @@
|
||||
build_using_cmake(args, toolchain_bin, args.build_path, targets)
|
||||
install(args, args.build_path, targets)
|
||||
else:
|
||||
- bin_path = swiftpm_bin_path(swift_exec, swiftpm_args, env)
|
||||
- swiftpm('build', swift_exec, swiftpm_args, env)
|
||||
+ bin_path = swiftpm_bin_path(swiftpm_exec, swiftpm_args, env)
|
||||
+ swiftpm('build', swiftpm_exec, swiftpm_args, env)
|
||||
non_darwin_install(args, bin_path)
|
||||
else:
|
||||
assert False, 'unknown action \'{}\''.format(args.action)
|
||||
diff --git a/swiftpm/Utilities/bootstrap b/swiftpm/Utilities/bootstrap
|
||||
index 6ae084e9..379d1738 100755
|
||||
--- a/swiftpm/Utilities/bootstrap
|
||||
+++ b/swiftpm/Utilities/bootstrap
|
||||
@@ -211,8 +211,9 @@ def parse_build_args(args):
|
||||
args.bootstrap_dir = os.path.join(args.target_dir, "bootstrap")
|
||||
args.conf = 'release' if args.release else 'debug'
|
||||
args.bin_dir = os.path.join(args.target_dir, args.conf)
|
||||
- args.bootstrap = not args.skip_cmake_bootstrap or \
|
||||
- not os.path.exists(os.path.join(os.path.split(args.swiftc_path)[0], "swift-build"))
|
||||
+ args.bootstrap = not args.skip_cmake_bootstrap or \
|
||||
+ (not (args.cross_compile_hosts and re.match('android-aarch64', args.cross_compile_hosts)) and \
|
||||
+ not os.path.exists(os.path.join(os.path.split(args.swiftc_path)[0], "swift-build")))
|
||||
|
||||
def parse_test_args(args):
|
||||
"""Parses and cleans arguments necessary for the test action."""
|
||||
@@ -622,7 +623,10 @@ def build_swiftpm_with_swiftpm(args, integrated_swift_driver):
|
||||
swiftpm_args.append(os.path.join(args.bootstrap_dir, "bin/swift-build"))
|
||||
else:
|
||||
note("Building SwiftPM (with a prebuilt swift-build)")
|
||||
- swiftpm_args.append(os.path.join(os.path.split(args.swiftc_path)[0], "swift-build"))
|
||||
+ if args.cross_compile_hosts and re.match('android-aarch64', args.cross_compile_hosts):
|
||||
+ swiftpm_args.append(os.path.join(os.path.realpath(os.getenv("SWIFT_BINDIR")), "swift-build"))
|
||||
+ else:
|
||||
+ swiftpm_args.append(os.path.join(os.path.split(args.swiftc_path)[0], "swift-build"))
|
||||
|
||||
swiftpm_args.append("--disable-sandbox")
|
||||
|
@ -112,9 +112,6 @@ PACKAGES+=" llvm-12-dev"
|
||||
PACKAGES+=" llvm-12-tools"
|
||||
PACKAGES+=" clang-12"
|
||||
|
||||
# Formerly needed by package rust. Not sure if needed by other packages.
|
||||
PACKAGES+=" clang-10"
|
||||
|
||||
# Needed for package smalltalk.
|
||||
PACKAGES+=" libsigsegv-dev"
|
||||
PACKAGES+=" zip"
|
||||
@ -130,6 +127,7 @@ PACKAGES+=" zlib1g-dev:i386"
|
||||
|
||||
# For swift.
|
||||
PACKAGES+=" lld"
|
||||
PACKAGES+=" patchelf"
|
||||
|
||||
# Needed by wrk.
|
||||
PACKAGES+=" luajit"
|
||||
|
Loading…
x
Reference in New Issue
Block a user