]> git.saurik.com Git - apple/objc4.git/blame - test/badCache.m
objc4-818.2.tar.gz
[apple/objc4.git] / test / badCache.m
CommitLineData
13ba007e
A
1/*
2TEST_CRASHES
3TEST_RUN_OUTPUT
4arm
5OK: badCache.m
6OR
7crash now
8objc\[\d+\]: Method cache corrupted.*
9objc\[\d+\]: .*
10objc\[\d+\]: .*
11objc\[\d+\]: .*
12objc\[\d+\]: .*
13objc\[\d+\]: Method cache corrupted.*
14objc\[\d+\]: HALTED
15END
16*/
17
18
19#include "test.h"
20
21// Test objc_msgSend's detection of infinite loops during cache scan.
22
23#if __arm__
24
25int main()
26{
27 testwarn("objc_msgSend on arm doesn't detect infinite loops");
28 fprintf(stderr, "arm\n");
29 succeed(__FILE__);
30}
31
32#else
33
34#include "testroot.i"
35
36#if __LP64__
37typedef uint32_t mask_t;
38#else
39typedef uint16_t mask_t;
40#endif
41
42struct bucket_t {
43 uintptr_t sel;
44 uintptr_t imp;
45};
46
47struct cache_t {
1807f628 48 uintptr_t buckets;
13ba007e
A
49 mask_t mask;
50 mask_t occupied;
51};
52
53struct class_t {
54 void *isa;
55 void *supercls;
56 struct cache_t cache;
57};
58
59@interface Subclass : TestRoot @end
60@implementation Subclass @end
61
62int main()
63{
64 Class cls = [TestRoot class];
65 id obj = [cls new];
66 [obj self];
67
68 struct cache_t *cache = &((__bridge struct class_t *)cls)->cache;
1807f628
A
69
70 // Figure out which cache mask scheme is in use by examining the existing bits.
71 int low4 = 0;
72#if __LP64__
73 int top16 = 0;
74#endif
75 int outlined = 0;
76
77 if (cache->buckets & 0xf) {
78 low4 = 1;
79#if __LP64__
80 } else if ((cache->buckets & (0xffffULL << 48))) {
81 top16 = 1;
82#endif
83 } else {
84 outlined = 1;
85 }
86
13ba007e 87# define COUNT 4
1807f628 88# define COUNTSHIFT 14
13ba007e
A
89 struct bucket_t *buckets = (struct bucket_t *)calloc(sizeof(struct bucket_t), COUNT+1);
90 for (int i = 0; i < COUNT; i++) {
91 buckets[i].sel = ~0;
92 buckets[i].imp = ~0;
93 }
94 buckets[COUNT].sel = 1;
95 buckets[COUNT].imp = (uintptr_t)buckets;
96
1807f628
A
97 if (low4) {
98 cache->buckets = (uintptr_t)buckets | COUNTSHIFT;
99#if __LP64__
100 } else if (top16) {
101 cache->buckets = ((uintptr_t)(COUNT - 1) << 48) | (uintptr_t)buckets;
102#endif
103 } else if (outlined) {
104 cache->mask = COUNT-1;
105 cache->buckets = (uintptr_t)buckets;
106 }
13ba007e 107
1807f628
A
108 cache->occupied = 0;
109
13ba007e
A
110 fprintf(stderr, "crash now\n");
111 [obj self];
112
113 fail("should have crashed");
114}
115
116#endif