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). */