1 // TEST_CONFIG OS=macosx,iphoneos,tvos,watchos
3 // This test checks that objc_msgSend's recovery path works correctly.
4 // It continuously runs msgSend on some background threads, then
5 // triggers the recovery path constantly as a stress test.
9 #include <dispatch/dispatch.h>
12 uintptr_t a, b, c, d, e, f, g;
15 @interface C1: TestRoot
18 - (id)idret { return nil; }
19 - (double)fpret { return 0.0; }
20 - (long double)lfpret { return 0.0; }
21 - (struct Big)stret { return (struct Big){}; }
27 - (id)idret { return [super idret]; }
28 - (double)fpret { return [super fpret]; }
29 - (long double)lfpret { return [super lfpret]; }
30 - (struct Big)stret { return [super stret]; }
33 EXTERN_C kern_return_t task_restartable_ranges_synchronize(task_t task);
35 EXTERN_C void sendWithMsgLookup(id self, SEL _cmd);
37 #if defined(__arm64__) && !__has_feature(ptrauth_calls)
39 "_sendWithMsgLookup: \n"
40 " stp fp, lr, [sp, #-16]! \n"
42 " bl _objc_msgLookup \n"
44 " ldp fp, lr, [sp], #16 \n"
47 #elif defined(__x86_64__)
49 "_sendWithMsgLookup: \n"
52 " callq _objc_msgLookup \n"
58 void sendWithMsgLookup(id self __unused, SEL _cmd __unused) {}
63 for(int i = 0; i < 2; i++) {
64 dispatch_async(dispatch_get_global_queue(0, 0), ^{
70 sendWithMsgLookup(obj, @selector(idret));
74 for(int i = 0; i < 1000000; i++) {
75 task_restartable_ranges_synchronize(mach_task_self());;