OC底层探索13-基于objc4-818的cache_t结构探索

作者: Henry________ | 来源:发表于2021-06-12 17:30 被阅读0次

    OC底层探索09-cache_t实现原理探索中已经对cache缓存的机制做了介绍,但是这文章是基于objc4-781来探索的。技术更新的太快了,在objc4-818中cache_t的结构又发生了很大的变化。与此同时缓存的过程中也有一些小的优化。

    objc4-781中的cache_t结构

    objc4-818中的cache_t结构

    • 通过一个指针 和 一个联合体来完成数据的存储。通过观察也只是对结构进行了一些优化,其他思路还是不变的。
    • 通过结构的变化,来兼容不同架构下的数据存储结构。相信一定是为了适应越来越多的架构。

    使用lldb来调试cache

    前提不变:使用lldb调试的前提是你需要有lib-objc的源码环境

    • 发现通过buckets()函数来进行lldb调试,和老版本并没有区别,有兴趣的可以通过最上方的链接去之前的文中看看。

    1. 脱离源码来调试cache(模拟器)

    前提: 模拟器环境

    本文的重头戏,脱离源码来进行调试和测试。

    //模拟器
    typedef uint32_t mask_t;
    
    struct HR_bucket_t {
        SEL sel;
        IMP imp;
    };
    
    struct HR_cache_t {
        uintptr_t _bucketsAndMaybeMask;
        union {
            struct {
                mask_t    _maybeMask;
                uint16_t                   _flags;
                uint16_t                   _occupied;
            };
        };
        
        //该方法是模仿源码
        static constexpr uintptr_t bucketsMask = ~0ul;
        struct HR_bucket_t* buckets() const
        {
            return (HR_bucket_t *)(_bucketsAndMaybeMask & bucketsMask);
        }
    };
    
    struct HR_class_data_bits_t {
        uintptr_t bits;
    };
    
    struct HR_objc_class {
        Class ISA;
        Class superclass;
        struct HR_cache_t cache;             // formerly cache pointer and vtable
        struct HR_class_data_bits_t bits;
    };
    

    调用

    int main() {
        HRTest * t = [HRTest alloc];
        
        struct HR_objc_class *obj = (__bridge struct HR_objc_class *)(HRTest.class);
            
        NSLog(@"mask:%u---occupied:%u",obj->cache._maybeMask,obj->cache._occupied);
    
        for (mask_t i = 0; i < obj->cache._maybeMask; i++) {
            struct HR_bucket_t bucket = obj->cache.buckets()[i];
            NSLog(@"sel:%@---imp:%p",NSStringFromSelector(bucket.sel),bucket.imp);
        }
    }
    

    查看结果

    • 在模拟下的结果和旧版本是一致的。

    2. 缓存过程中的一些优化

    • 定义FULL_UTILIZATION_CACHE_SIZE= 1 << 3 = 8小缓存区。应该是考虑到小缓存区时hash冲突不会造成太大性能损耗。
    • 多了这部分逻辑,相比于旧逻辑容量可以在4或者8的情况下全部放满。
    • 只有真机的情况下才生效

    相关文章

      网友评论

        本文标题:OC底层探索13-基于objc4-818的cache_t结构探索

        本文链接:https://www.haomeiwen.com/subject/shdieltx.html