文章目录
一、cache_t分析
#if defined(__arm64__) && __LP64__
#define CACHE_MASK_STORAGE CACHE_MASK_STORAGE_HIGH_16
#elif defined(__arm64__) && !__LP64__
#define CACHE_MASK_STORAGE CACHE_MASK_STORAGE_LOW_4
#else
#define CACHE_MASK_STORAGE CACHE_MASK_STORAGE_OUTLINED
#endif
struct bucket_t {
// IMP-first is better for arm64e ptrauth and no worse for arm64.
// SEL-first is better for armv7* and i386 and x86_64.
#if __arm64__
explicit_atomic<uintptr_t> _imp;
explicit_atomic<SEL> _sel;
#else
explicit_atomic<SEL> _sel;
explicit_atomic<uintptr_t> _imp;
#endif
}
struct cache_t {
#if CACHE_MASK_STORAGE == CACHE_MASK_STORAGE_OUTLINED
explicit_atomic<struct bucket_t *> _buckets;
explicit_atomic<mask_t> _mask;
#elif CACHE_MASK_STORAGE == CACHE_MASK_STORAGE_HIGH_16
explicit_atomic<uintptr_t> _maskAndBuckets;
mask_t _mask_unused;
......
#else
#error Unknown cache mask storage type.
#endif
#if __LP64__
uint16_t _flags;
#endif
uint16_t _occupied;
1 模拟器环境(i386、x86_64、armv7)
简化一下上面的代码,explicit_atomic的作用就是显式原子操作。
struct bucket_t {
SEL _sel;
uintptr_t _imp;
}
struct cache_t {
struct bucket_t * _buckets; //缓存的方法的SEL和IMP
mask_t _mask; //哈希掩码,开辟capacity - 1
uint16_t _flags; //缓存标识
uint16_t _occupied; //已占用的缓存空间
}
以前都是使用lldb进行内存偏移访问,今天通过打印直接访问
typedef uint32_t mask_t; // x86_64 & arm64 asm are less efficient with 16-bits
struct gc_bucket_t {
SEL _sel;
IMP _imp;
};
struct gc_cache_t {
struct gc_bucket_t *_buckets;
mask_t _mask;
uint16_t _flags;
uint16_t _occupied;
};
struct gc_class_data_bits_t {
uintptr_t bits;
};
struct gc_objc_class {
Class ISA;
Class superclass;
struct gc_cache_t cache; // formerly cache pointer and vtable
struct gc_class_data_bits_t bits; // class_rw_t * plus custom rr/alloc flags
};
@interface TestA : NSObject
- (void)test1;
- (void)test2;
- (void)test3;
- (void)test4;
- (void)test5;
- (void)test6;
@end
@implementation TestA
- (void)test1 {
NSLog(@"TestA method name : %s", __func__);
}
- (void)test2 {
NSLog(@"TestA method name : %s", __func__);
}
- (void)test3 {
NSLog(@"TestA method name : %s", __func__);
}
- (void)test4 {
NSLog(@"TestA method name : %s", __func__);
}
- (void)test5 {
NSLog(@"TestA method name : %s", __func__);
}
- (void)test6 {
NSLog(@"TestA method name : %s", __func__);
}
@end
void log_cache_t(struct gc_cache_t cache) {
for (mask_t i = 0 ; i < cache._mask; i++) {
// 打印获取的 bucket
struct gc_bucket_t bucket = cache._buckets[i];
NSLog(@"bucket._sel=%@ - bucket._imp=%p",NSStringFromSelector(bucket._sel),bucket._imp);
}
NSLog(@"_mask=%u, _flags=%hu, _occupied=%hu", cache._mask, cache._flags, cache._occupied);
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
TestA *testA = [[TestA alloc] init];
struct gc_objc_class *cls = (__bridge struct gc_objc_class *)[TestA class];
log_cache_t<