From 4a8d125b3f0ea406df5fbfef8ab6747ac2dcccdc Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Mon, 11 Feb 2019 16:43:04 +0000 Subject: [PATCH] Fix linkage type for objc_method_cache_version. This was accidentally common linkage, so ended up with copy relocations. --- dtable.c | 2 ++ objc/slot.h | 36 +++++++++++++++++------------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/dtable.c b/dtable.c index 139bcc5..36d0b32 100644 --- a/dtable.c +++ b/dtable.c @@ -43,6 +43,8 @@ PRIVATE mutex_t initialize_lock; * 2^x in increments of 8. */ static uint32_t dtable_depth = 8; +_Atomic(uint64_t) objc_method_cache_version; + /** * Starting at `cls`, finds the class that provides the implementation of the * method identified by `sel`. diff --git a/objc/slot.h b/objc/slot.h index f082db9..59afe19 100644 --- a/objc/slot.h +++ b/objc/slot.h @@ -6,32 +6,30 @@ #define __OBJC_SLOT_H_INCLUDED__ /** * The objc_slot structure is used to permit safe IMP caching. It is returned - * by the new lookup APIs. When you cache an IMP, you should store a copy of - * the version field and a pointer to the slot. - * - * The slot version is guaranteed never to be 0. When updating a cache, you - * should use code of the following form: - * - * 1) version = 0; - * 2) slot->cachedFor = receiver->isa; - * 3) slot_cache = slot; - * 4) version = slot->version; - * - * The runtime guarantees that the version in any cachable slot will never be - * 0. This should ensure that, if the version and cache pointer mismatch, the - * next access will cause a cache miss. - * - * When using a cached slot, you should compare the owner pointer to the isa - * pointer of the receiver and the message and the version of the slot to your - * cached version. + * by the new lookup APIs. When you call `objc_slot_lookup_version`, the final + * parameter is used to return either the current value of + * `objc_method_cache_version` or 0 if the slot is uncacheable. You can then + * store this value along with a pointer to the `objc_slot2`. If the returned + * value is equal to the current value of `objc_method_cache_version` then it + * is safe to call the method from the `method` field of the slot directly. */ struct objc_slot2 { IMP method; } OBJC_NONPORTABLE; -_Atomic(uint64_t) objc_method_cache_version; +/** + * A counter that is incremented whenever one or more cached slots become + * invalid, for example if a subclass loads a category containing methods that + * were inherited from the superclass. + */ +PUBLIC _Atomic(uint64_t) objc_method_cache_version; +/** + * Legacy cache structure. This is no longer maintained in the runtime and is + * now exported only in the compatibility interfaces. Slots of this form are + * never cacheable. + */ struct objc_slot { /** The class to which this slot is attached (used internally). */