From 78dd69809765a2d850a0a1da0454af70c7cc9e3b Mon Sep 17 00:00:00 2001 From: Mike Ash Date: Wed, 8 May 2019 15:10:41 -0400 Subject: [PATCH] [Runtime] Use a #define for the value of swift_isaMask. This allows _swift_getClassOfAllocated to use a constant instead of loading from a global, and allows swift_isaMask to be computed without a static initializer. Debug builds verify that the #define matches the value from libobjc. rdar://problem/22375602 rdar://problem/46385113 --- stdlib/public/runtime/Private.h | 24 +++++++++++++++++++++++- stdlib/public/runtime/SwiftObject.mm | 19 +++++++------------ 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/stdlib/public/runtime/Private.h b/stdlib/public/runtime/Private.h index 1db106bc0619b..40066912b2150 100644 --- a/stdlib/public/runtime/Private.h +++ b/stdlib/public/runtime/Private.h @@ -22,6 +22,10 @@ #include "swift/Runtime/Metadata.h" #include "llvm/Support/Compiler.h" +#if defined(__APPLE__) && defined(__MACH__) +#include +#endif + // Opaque ISAs need to use object_getClass which is in runtime.h #if SWIFT_HAS_OPAQUE_ISAS #include @@ -84,6 +88,24 @@ class TypeInfo { #if SWIFT_HAS_ISA_MASKING SWIFT_RUNTIME_EXPORT uintptr_t swift_isaMask; + +// Hardcode the mask. We have our own copy of the value, as it's hard to work +// out the proper includes from libobjc. The values MUST match the ones from +// libobjc. Debug builds check these values against objc_debug_isa_class_mask +// from libobjc. +# if TARGET_OS_SIMULATOR +// Simulators don't currently use isa masking, but we still want to emit +// swift_isaMask and the corresponding code in case that changes. libobjc's +// mask has the bottom bits clear to include pointer alignment, match that +// value here. +# define SWIFT_ISA_MASK 0xfffffffffffffff8ULL +# elif __arm64__ +# define SWIFT_ISA_MASK 0x0000000ffffffff8ULL +# elif __x86_64__ +# define SWIFT_ISA_MASK 0x00007ffffffffff8ULL +# else +# error Unknown architecture for masked isa. +# endif #endif #if SWIFT_OBJC_INTEROP @@ -134,7 +156,7 @@ class TypeInfo { #if SWIFT_HAS_ISA_MASKING // Apply the mask. - bits &= swift_isaMask; + bits &= SWIFT_ISA_MASK; #endif // The result is a class pointer. diff --git a/stdlib/public/runtime/SwiftObject.mm b/stdlib/public/runtime/SwiftObject.mm index 4c0ee81d37640..b644c80f60d69 100644 --- a/stdlib/public/runtime/SwiftObject.mm +++ b/stdlib/public/runtime/SwiftObject.mm @@ -58,17 +58,7 @@ OBJC_EXPORT __attribute__((__weak_import__)) const uintptr_t objc_debug_isa_class_mask; -static uintptr_t computeISAMask() { - // The versions of the Objective-C runtime which use non-pointer - // ISAs also export this symbol. - if (auto runtimeSymbol = &objc_debug_isa_class_mask) - return *runtimeSymbol; - return ~uintptr_t(0); -} - -SWIFT_ALLOWED_RUNTIME_GLOBAL_CTOR_BEGIN -uintptr_t swift::swift_isaMask = computeISAMask(); -SWIFT_ALLOWED_RUNTIME_GLOBAL_CTOR_END +uintptr_t swift::swift_isaMask = SWIFT_ISA_MASK; #endif const ClassMetadata *swift::_swift_getClass(const void *object) { @@ -204,7 +194,12 @@ Class _swift_classOfObjCHeapObject(OpaqueValue *value) { @implementation SwiftObject -+ (void)initialize {} ++ (void)initialize { +#if SWIFT_HAS_ISA_MASKING + assert(&objc_debug_isa_class_mask); + assert(objc_debug_isa_class_mask == SWIFT_ISA_MASK); +#endif +} + (instancetype)allocWithZone:(struct _NSZone *)zone { assert(zone == nullptr);