]> git.saurik.com Git - apple/objc4.git/blob - runtime/objc-cache.mm
objc4-779.1.tar.gz
[apple/objc4.git] / runtime / objc-cache.mm
1 /*
2 * Copyright (c) 1999-2007 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /***********************************************************************
25 * objc-cache.m
26 * Method cache management
27 * Cache flushing
28 * Cache garbage collection
29 * Cache instrumentation
30 * Dedicated allocator for large caches
31 **********************************************************************/
32
33
34 /***********************************************************************
35 * Method cache locking (GrP 2001-1-14)
36 *
37 * For speed, objc_msgSend does not acquire any locks when it reads
38 * method caches. Instead, all cache changes are performed so that any
39 * objc_msgSend running concurrently with the cache mutator will not
40 * crash or hang or get an incorrect result from the cache.
41 *
42 * When cache memory becomes unused (e.g. the old cache after cache
43 * expansion), it is not immediately freed, because a concurrent
44 * objc_msgSend could still be using it. Instead, the memory is
45 * disconnected from the data structures and placed on a garbage list.
46 * The memory is now only accessible to instances of objc_msgSend that
47 * were running when the memory was disconnected; any further calls to
48 * objc_msgSend will not see the garbage memory because the other data
49 * structures don't point to it anymore. The collecting_in_critical
50 * function checks the PC of all threads and returns FALSE when all threads
51 * are found to be outside objc_msgSend. This means any call to objc_msgSend
52 * that could have had access to the garbage has finished or moved past the
53 * cache lookup stage, so it is safe to free the memory.
54 *
55 * All functions that modify cache data or structures must acquire the
56 * cacheUpdateLock to prevent interference from concurrent modifications.
57 * The function that frees cache garbage must acquire the cacheUpdateLock
58 * and use collecting_in_critical() to flush out cache readers.
59 * The cacheUpdateLock is also used to protect the custom allocator used
60 * for large method cache blocks.
61 *
62 * Cache readers (PC-checked by collecting_in_critical())
63 * objc_msgSend*
64 * cache_getImp
65 *
66 * Cache writers (hold cacheUpdateLock while reading or writing; not PC-checked)
67 * cache_fill (acquires lock)
68 * cache_expand (only called from cache_fill)
69 * cache_create (only called from cache_expand)
70 * bcopy (only called from instrumented cache_expand)
71 * flush_caches (acquires lock)
72 * cache_flush (only called from cache_fill and flush_caches)
73 * cache_collect_free (only called from cache_expand and cache_flush)
74 *
75 * UNPROTECTED cache readers (NOT thread-safe; used for debug info only)
76 * cache_print
77 * _class_printMethodCaches
78 * _class_printDuplicateCacheEntries
79 * _class_printMethodCacheStatistics
80 *
81 ***********************************************************************/
82
83
84 #if __OBJC2__
85
86 #include "objc-private.h"
87 #include "objc-cache.h"
88
89
90 /* Initial cache bucket count. INIT_CACHE_SIZE must be a power of two. */
91 enum {
92 INIT_CACHE_SIZE_LOG2 = 2,
93 INIT_CACHE_SIZE = (1 << INIT_CACHE_SIZE_LOG2),
94 MAX_CACHE_SIZE_LOG2 = 16,
95 MAX_CACHE_SIZE = (1 << MAX_CACHE_SIZE_LOG2),
96 };
97
98 static void cache_collect_free(struct bucket_t *data, mask_t capacity);
99 static int _collecting_in_critical(void);
100 static void _garbage_make_room(void);
101
102
103 /***********************************************************************
104 * Cache statistics for OBJC_PRINT_CACHE_SETUP
105 **********************************************************************/
106 static unsigned int cache_counts[16];
107 static size_t cache_allocations;
108 static size_t cache_collections;
109
110 static void recordNewCache(mask_t capacity)
111 {
112 size_t bucket = log2u(capacity);
113 if (bucket < countof(cache_counts)) {
114 cache_counts[bucket]++;
115 }
116 cache_allocations++;
117 }
118
119 static void recordDeadCache(mask_t capacity)
120 {
121 size_t bucket = log2u(capacity);
122 if (bucket < countof(cache_counts)) {
123 cache_counts[bucket]--;
124 }
125 }
126
127 /***********************************************************************
128 * Pointers used by compiled class objects
129 * These use asm to avoid conflicts with the compiler's internal declarations
130 **********************************************************************/
131
132 // EMPTY_BYTES includes space for a cache end marker bucket.
133 // This end marker doesn't actually have the wrap-around pointer
134 // because cache scans always find an empty bucket before they might wrap.
135 // 1024 buckets is fairly common.
136 #if DEBUG
137 // Use a smaller size to exercise heap-allocated empty caches.
138 # define EMPTY_BYTES ((8+1)*16)
139 #else
140 # define EMPTY_BYTES ((1024+1)*16)
141 #endif
142
143 #define stringize(x) #x
144 #define stringize2(x) stringize(x)
145
146 // "cache" is cache->buckets; "vtable" is cache->mask/occupied
147 // hack to avoid conflicts with compiler's internal declaration
148 asm("\n .section __TEXT,__const"
149 "\n .globl __objc_empty_vtable"
150 "\n .set __objc_empty_vtable, 0"
151 "\n .globl __objc_empty_cache"
152 #if CACHE_MASK_STORAGE == CACHE_MASK_STORAGE_LOW_4
153 "\n .align 4"
154 "\n L__objc_empty_cache: .space " stringize2(EMPTY_BYTES)
155 "\n .set __objc_empty_cache, L__objc_empty_cache + 0xf"
156 #else
157 "\n .align 3"
158 "\n __objc_empty_cache: .space " stringize2(EMPTY_BYTES)
159 #endif
160 );
161
162
163 #if __arm__ || __x86_64__ || __i386__
164 // objc_msgSend has few registers available.
165 // Cache scan increments and wraps at special end-marking bucket.
166 #define CACHE_END_MARKER 1
167 static inline mask_t cache_next(mask_t i, mask_t mask) {
168 return (i+1) & mask;
169 }
170
171 #elif __arm64__
172 // objc_msgSend has lots of registers available.
173 // Cache scan decrements. No end marker needed.
174 #define CACHE_END_MARKER 0
175 static inline mask_t cache_next(mask_t i, mask_t mask) {
176 return i ? i-1 : mask;
177 }
178
179 #else
180 #error unknown architecture
181 #endif
182
183
184 // mega_barrier doesn't really work, but it works enough on ARM that
185 // we leave well enough alone and keep using it there.
186 #if __arm__
187 #define mega_barrier() \
188 __asm__ __volatile__( \
189 "dsb ish" \
190 : : : "memory")
191
192 #endif
193
194 #if __arm64__
195
196 // Pointer-size register prefix for inline asm
197 # if __LP64__
198 # define p "x" // true arm64
199 # else
200 # define p "w" // arm64_32
201 # endif
202
203 // Use atomic double-word instructions to update cache entries.
204 // This requires cache buckets not cross cache line boundaries.
205 static ALWAYS_INLINE void
206 stp(uintptr_t onep, uintptr_t twop, void *destp)
207 {
208 __asm__ ("stp %" p "[one], %" p "[two], [%x[dest]]"
209 : "=m" (((uintptr_t *)(destp))[0]),
210 "=m" (((uintptr_t *)(destp))[1])
211 : [one] "r" (onep),
212 [two] "r" (twop),
213 [dest] "r" (destp)
214 : /* no clobbers */
215 );
216 }
217
218 static ALWAYS_INLINE void __unused
219 ldp(uintptr_t& onep, uintptr_t& twop, const void *srcp)
220 {
221 __asm__ ("ldp %" p "[one], %" p "[two], [%x[src]]"
222 : [one] "=r" (onep),
223 [two] "=r" (twop)
224 : "m" (((const uintptr_t *)(srcp))[0]),
225 "m" (((const uintptr_t *)(srcp))[1]),
226 [src] "r" (srcp)
227 : /* no clobbers */
228 );
229 }
230
231 #undef p
232 #endif
233
234
235 // Class points to cache. SEL is key. Cache buckets store SEL+IMP.
236 // Caches are never built in the dyld shared cache.
237
238 static inline mask_t cache_hash(SEL sel, mask_t mask)
239 {
240 return (mask_t)(uintptr_t)sel & mask;
241 }
242
243 cache_t *getCache(Class cls)
244 {
245 ASSERT(cls);
246 return &cls->cache;
247 }
248
249 #if __arm64__
250
251 template<Atomicity atomicity, IMPEncoding impEncoding>
252 void bucket_t::set(SEL newSel, IMP newImp, Class cls)
253 {
254 ASSERT(_sel.load(memory_order::memory_order_relaxed) == 0 ||
255 _sel.load(memory_order::memory_order_relaxed) == newSel);
256
257 static_assert(offsetof(bucket_t,_imp) == 0 &&
258 offsetof(bucket_t,_sel) == sizeof(void *),
259 "bucket_t layout doesn't match arm64 bucket_t::set()");
260
261 uintptr_t encodedImp = (impEncoding == Encoded
262 ? encodeImp(newImp, newSel, cls)
263 : (uintptr_t)newImp);
264
265 // LDP/STP guarantees that all observers get
266 // either imp/sel or newImp/newSel
267 stp(encodedImp, (uintptr_t)newSel, this);
268 }
269
270 #else
271
272 template<Atomicity atomicity, IMPEncoding impEncoding>
273 void bucket_t::set(SEL newSel, IMP newImp, Class cls)
274 {
275 ASSERT(_sel.load(memory_order::memory_order_relaxed) == 0 ||
276 _sel.load(memory_order::memory_order_relaxed) == newSel);
277
278 // objc_msgSend uses sel and imp with no locks.
279 // It is safe for objc_msgSend to see new imp but NULL sel
280 // (It will get a cache miss but not dispatch to the wrong place.)
281 // It is unsafe for objc_msgSend to see old imp and new sel.
282 // Therefore we write new imp, wait a lot, then write new sel.
283
284 uintptr_t newIMP = (impEncoding == Encoded
285 ? encodeImp(newImp, newSel, cls)
286 : (uintptr_t)newImp);
287
288 if (atomicity == Atomic) {
289 _imp.store(newIMP, memory_order::memory_order_relaxed);
290
291 if (_sel.load(memory_order::memory_order_relaxed) != newSel) {
292 #ifdef __arm__
293 mega_barrier();
294 _sel.store(newSel, memory_order::memory_order_relaxed);
295 #elif __x86_64__ || __i386__
296 _sel.store(newSel, memory_order::memory_order_release);
297 #else
298 #error Don't know how to do bucket_t::set on this architecture.
299 #endif
300 }
301 } else {
302 _imp.store(newIMP, memory_order::memory_order_relaxed);
303 _sel.store(newSel, memory_order::memory_order_relaxed);
304 }
305 }
306
307 #endif
308
309 #if CACHE_MASK_STORAGE == CACHE_MASK_STORAGE_OUTLINED
310
311 void cache_t::setBucketsAndMask(struct bucket_t *newBuckets, mask_t newMask)
312 {
313 // objc_msgSend uses mask and buckets with no locks.
314 // It is safe for objc_msgSend to see new buckets but old mask.
315 // (It will get a cache miss but not overrun the buckets' bounds).
316 // It is unsafe for objc_msgSend to see old buckets and new mask.
317 // Therefore we write new buckets, wait a lot, then write new mask.
318 // objc_msgSend reads mask first, then buckets.
319
320 #ifdef __arm__
321 // ensure other threads see buckets contents before buckets pointer
322 mega_barrier();
323
324 _buckets.store(newBuckets, memory_order::memory_order_relaxed);
325
326 // ensure other threads see new buckets before new mask
327 mega_barrier();
328
329 _mask.store(newMask, memory_order::memory_order_relaxed);
330 _occupied = 0;
331 #elif __x86_64__ || i386
332 // ensure other threads see buckets contents before buckets pointer
333 _buckets.store(newBuckets, memory_order::memory_order_release);
334
335 // ensure other threads see new buckets before new mask
336 _mask.store(newMask, memory_order::memory_order_release);
337 _occupied = 0;
338 #else
339 #error Don't know how to do setBucketsAndMask on this architecture.
340 #endif
341 }
342
343 struct bucket_t *cache_t::emptyBuckets()
344 {
345 return (bucket_t *)&_objc_empty_cache;
346 }
347
348 struct bucket_t *cache_t::buckets()
349 {
350 return _buckets.load(memory_order::memory_order_relaxed);
351 }
352
353 mask_t cache_t::mask()
354 {
355 return _mask.load(memory_order::memory_order_relaxed);
356 }
357
358 void cache_t::initializeToEmpty()
359 {
360 bzero(this, sizeof(*this));
361 _buckets.store((bucket_t *)&_objc_empty_cache, memory_order::memory_order_relaxed);
362 }
363
364 #elif CACHE_MASK_STORAGE == CACHE_MASK_STORAGE_HIGH_16
365
366 void cache_t::setBucketsAndMask(struct bucket_t *newBuckets, mask_t newMask)
367 {
368 uintptr_t buckets = (uintptr_t)newBuckets;
369 uintptr_t mask = (uintptr_t)newMask;
370
371 ASSERT(buckets <= bucketsMask);
372 ASSERT(mask <= maxMask);
373
374 _maskAndBuckets.store(((uintptr_t)newMask << maskShift) | (uintptr_t)newBuckets, std::memory_order_relaxed);
375 _occupied = 0;
376 }
377
378 struct bucket_t *cache_t::emptyBuckets()
379 {
380 return (bucket_t *)&_objc_empty_cache;
381 }
382
383 struct bucket_t *cache_t::buckets()
384 {
385 uintptr_t maskAndBuckets = _maskAndBuckets.load(memory_order::memory_order_relaxed);
386 return (bucket_t *)(maskAndBuckets & bucketsMask);
387 }
388
389 mask_t cache_t::mask()
390 {
391 uintptr_t maskAndBuckets = _maskAndBuckets.load(memory_order::memory_order_relaxed);
392 return maskAndBuckets >> maskShift;
393 }
394
395 void cache_t::initializeToEmpty()
396 {
397 bzero(this, sizeof(*this));
398 _maskAndBuckets.store((uintptr_t)&_objc_empty_cache, std::memory_order_relaxed);
399 }
400
401 #elif CACHE_MASK_STORAGE == CACHE_MASK_STORAGE_LOW_4
402
403 void cache_t::setBucketsAndMask(struct bucket_t *newBuckets, mask_t newMask)
404 {
405 uintptr_t buckets = (uintptr_t)newBuckets;
406 unsigned mask = (unsigned)newMask;
407
408 ASSERT(buckets == (buckets & bucketsMask));
409 ASSERT(mask <= 0xffff);
410
411 // The shift amount is equal to the number of leading zeroes in
412 // the last 16 bits of mask. Count all the leading zeroes, then
413 // subtract to ignore the top half.
414 uintptr_t maskShift = __builtin_clz(mask) - (sizeof(mask) * CHAR_BIT - 16);
415 ASSERT(mask == (0xffff >> maskShift));
416
417 _maskAndBuckets.store(buckets | maskShift, memory_order::memory_order_relaxed);
418 _occupied = 0;
419
420 ASSERT(this->buckets() == newBuckets);
421 ASSERT(this->mask() == newMask);
422 }
423
424 struct bucket_t *cache_t::emptyBuckets()
425 {
426 return (bucket_t *)((uintptr_t)&_objc_empty_cache & bucketsMask);
427 }
428
429 struct bucket_t *cache_t::buckets()
430 {
431 uintptr_t maskAndBuckets = _maskAndBuckets.load(memory_order::memory_order_relaxed);
432 return (bucket_t *)(maskAndBuckets & bucketsMask);
433 }
434
435 mask_t cache_t::mask()
436 {
437 uintptr_t maskAndBuckets = _maskAndBuckets.load(memory_order::memory_order_relaxed);
438 uintptr_t maskShift = (maskAndBuckets & maskMask);
439 return 0xffff >> maskShift;
440 }
441
442 void cache_t::initializeToEmpty()
443 {
444 bzero(this, sizeof(*this));
445 _maskAndBuckets.store((uintptr_t)&_objc_empty_cache, std::memory_order_relaxed);
446 }
447
448 #else
449 #error Unknown cache mask storage type.
450 #endif
451
452 mask_t cache_t::occupied()
453 {
454 return _occupied;
455 }
456
457 void cache_t::incrementOccupied()
458 {
459 _occupied++;
460 }
461
462 unsigned cache_t::capacity()
463 {
464 return mask() ? mask()+1 : 0;
465 }
466
467
468 #if CACHE_END_MARKER
469
470 size_t cache_t::bytesForCapacity(uint32_t cap)
471 {
472 // fixme put end marker inline when capacity+1 malloc is inefficient
473 return sizeof(bucket_t) * (cap + 1);
474 }
475
476 bucket_t *cache_t::endMarker(struct bucket_t *b, uint32_t cap)
477 {
478 // bytesForCapacity() chooses whether the end marker is inline or not
479 return (bucket_t *)((uintptr_t)b + bytesForCapacity(cap)) - 1;
480 }
481
482 bucket_t *allocateBuckets(mask_t newCapacity)
483 {
484 // Allocate one extra bucket to mark the end of the list.
485 // This can't overflow mask_t because newCapacity is a power of 2.
486 // fixme instead put the end mark inline when +1 is malloc-inefficient
487 bucket_t *newBuckets = (bucket_t *)
488 calloc(cache_t::bytesForCapacity(newCapacity), 1);
489
490 bucket_t *end = cache_t::endMarker(newBuckets, newCapacity);
491
492 #if __arm__
493 // End marker's sel is 1 and imp points BEFORE the first bucket.
494 // This saves an instruction in objc_msgSend.
495 end->set<NotAtomic, Raw>((SEL)(uintptr_t)1, (IMP)(newBuckets - 1), nil);
496 #else
497 // End marker's sel is 1 and imp points to the first bucket.
498 end->set<NotAtomic, Raw>((SEL)(uintptr_t)1, (IMP)newBuckets, nil);
499 #endif
500
501 if (PrintCaches) recordNewCache(newCapacity);
502
503 return newBuckets;
504 }
505
506 #else
507
508 size_t cache_t::bytesForCapacity(uint32_t cap)
509 {
510 return sizeof(bucket_t) * cap;
511 }
512
513 bucket_t *allocateBuckets(mask_t newCapacity)
514 {
515 if (PrintCaches) recordNewCache(newCapacity);
516
517 return (bucket_t *)calloc(cache_t::bytesForCapacity(newCapacity), 1);
518 }
519
520 #endif
521
522
523 bucket_t *emptyBucketsForCapacity(mask_t capacity, bool allocate = true)
524 {
525 #if CONFIG_USE_CACHE_LOCK
526 cacheUpdateLock.assertLocked();
527 #else
528 runtimeLock.assertLocked();
529 #endif
530
531 size_t bytes = cache_t::bytesForCapacity(capacity);
532
533 // Use _objc_empty_cache if the buckets is small enough.
534 if (bytes <= EMPTY_BYTES) {
535 return cache_t::emptyBuckets();
536 }
537
538 // Use shared empty buckets allocated on the heap.
539 static bucket_t **emptyBucketsList = nil;
540 static mask_t emptyBucketsListCount = 0;
541
542 mask_t index = log2u(capacity);
543
544 if (index >= emptyBucketsListCount) {
545 if (!allocate) return nil;
546
547 mask_t newListCount = index + 1;
548 bucket_t *newBuckets = (bucket_t *)calloc(bytes, 1);
549 emptyBucketsList = (bucket_t**)
550 realloc(emptyBucketsList, newListCount * sizeof(bucket_t *));
551 // Share newBuckets for every un-allocated size smaller than index.
552 // The array is therefore always fully populated.
553 for (mask_t i = emptyBucketsListCount; i < newListCount; i++) {
554 emptyBucketsList[i] = newBuckets;
555 }
556 emptyBucketsListCount = newListCount;
557
558 if (PrintCaches) {
559 _objc_inform("CACHES: new empty buckets at %p (capacity %zu)",
560 newBuckets, (size_t)capacity);
561 }
562 }
563
564 return emptyBucketsList[index];
565 }
566
567
568 bool cache_t::isConstantEmptyCache()
569 {
570 return
571 occupied() == 0 &&
572 buckets() == emptyBucketsForCapacity(capacity(), false);
573 }
574
575 bool cache_t::canBeFreed()
576 {
577 return !isConstantEmptyCache();
578 }
579
580 ALWAYS_INLINE
581 void cache_t::reallocate(mask_t oldCapacity, mask_t newCapacity, bool freeOld)
582 {
583 bucket_t *oldBuckets = buckets();
584 bucket_t *newBuckets = allocateBuckets(newCapacity);
585
586 // Cache's old contents are not propagated.
587 // This is thought to save cache memory at the cost of extra cache fills.
588 // fixme re-measure this
589
590 ASSERT(newCapacity > 0);
591 ASSERT((uintptr_t)(mask_t)(newCapacity-1) == newCapacity-1);
592
593 setBucketsAndMask(newBuckets, newCapacity - 1);
594
595 if (freeOld) {
596 cache_collect_free(oldBuckets, oldCapacity);
597 }
598 }
599
600
601 void cache_t::bad_cache(id receiver, SEL sel, Class isa)
602 {
603 // Log in separate steps in case the logging itself causes a crash.
604 _objc_inform_now_and_on_crash
605 ("Method cache corrupted. This may be a message to an "
606 "invalid object, or a memory error somewhere else.");
607 cache_t *cache = &isa->cache;
608 #if CACHE_MASK_STORAGE == CACHE_MASK_STORAGE_OUTLINED
609 bucket_t *buckets = cache->_buckets.load(memory_order::memory_order_relaxed);
610 _objc_inform_now_and_on_crash
611 ("%s %p, SEL %p, isa %p, cache %p, buckets %p, "
612 "mask 0x%x, occupied 0x%x",
613 receiver ? "receiver" : "unused", receiver,
614 sel, isa, cache, buckets,
615 cache->_mask.load(memory_order::memory_order_relaxed),
616 cache->_occupied);
617 _objc_inform_now_and_on_crash
618 ("%s %zu bytes, buckets %zu bytes",
619 receiver ? "receiver" : "unused", malloc_size(receiver),
620 malloc_size(buckets));
621 #elif (CACHE_MASK_STORAGE == CACHE_MASK_STORAGE_HIGH_16 || \
622 CACHE_MASK_STORAGE == CACHE_MASK_STORAGE_LOW_4)
623 uintptr_t maskAndBuckets = cache->_maskAndBuckets.load(memory_order::memory_order_relaxed);
624 _objc_inform_now_and_on_crash
625 ("%s %p, SEL %p, isa %p, cache %p, buckets and mask 0x%lx, "
626 "occupied 0x%x",
627 receiver ? "receiver" : "unused", receiver,
628 sel, isa, cache, maskAndBuckets,
629 cache->_occupied);
630 _objc_inform_now_and_on_crash
631 ("%s %zu bytes, buckets %zu bytes",
632 receiver ? "receiver" : "unused", malloc_size(receiver),
633 malloc_size(cache->buckets()));
634 #else
635 #error Unknown cache mask storage type.
636 #endif
637 _objc_inform_now_and_on_crash
638 ("selector '%s'", sel_getName(sel));
639 _objc_inform_now_and_on_crash
640 ("isa '%s'", isa->nameForLogging());
641 _objc_fatal
642 ("Method cache corrupted. This may be a message to an "
643 "invalid object, or a memory error somewhere else.");
644 }
645
646 ALWAYS_INLINE
647 void cache_t::insert(Class cls, SEL sel, IMP imp, id receiver)
648 {
649 #if CONFIG_USE_CACHE_LOCK
650 cacheUpdateLock.assertLocked();
651 #else
652 runtimeLock.assertLocked();
653 #endif
654
655 ASSERT(sel != 0 && cls->isInitialized());
656
657 // Use the cache as-is if it is less than 3/4 full
658 mask_t newOccupied = occupied() + 1;
659 unsigned oldCapacity = capacity(), capacity = oldCapacity;
660 if (slowpath(isConstantEmptyCache())) {
661 // Cache is read-only. Replace it.
662 if (!capacity) capacity = INIT_CACHE_SIZE;
663 reallocate(oldCapacity, capacity, /* freeOld */false);
664 }
665 else if (fastpath(newOccupied <= capacity / 4 * 3)) {
666 // Cache is less than 3/4 full. Use it as-is.
667 }
668 else {
669 capacity = capacity ? capacity * 2 : INIT_CACHE_SIZE;
670 if (capacity > MAX_CACHE_SIZE) {
671 capacity = MAX_CACHE_SIZE;
672 }
673 reallocate(oldCapacity, capacity, true);
674 }
675
676 bucket_t *b = buckets();
677 mask_t m = capacity - 1;
678 mask_t begin = cache_hash(sel, m);
679 mask_t i = begin;
680
681 // Scan for the first unused slot and insert there.
682 // There is guaranteed to be an empty slot because the
683 // minimum size is 4 and we resized at 3/4 full.
684 do {
685 if (fastpath(b[i].sel() == 0)) {
686 incrementOccupied();
687 b[i].set<Atomic, Encoded>(sel, imp, cls);
688 return;
689 }
690 if (b[i].sel() == sel) {
691 // The entry was added to the cache by some other thread
692 // before we grabbed the cacheUpdateLock.
693 return;
694 }
695 } while (fastpath((i = cache_next(i, m)) != begin));
696
697 cache_t::bad_cache(receiver, (SEL)sel, cls);
698 }
699
700 void cache_fill(Class cls, SEL sel, IMP imp, id receiver)
701 {
702 runtimeLock.assertLocked();
703
704 #if !DEBUG_TASK_THREADS
705 // Never cache before +initialize is done
706 if (cls->isInitialized()) {
707 cache_t *cache = getCache(cls);
708 #if CONFIG_USE_CACHE_LOCK
709 mutex_locker_t lock(cacheUpdateLock);
710 #endif
711 cache->insert(cls, sel, imp, receiver);
712 }
713 #else
714 _collecting_in_critical();
715 #endif
716 }
717
718
719 // Reset this entire cache to the uncached lookup by reallocating it.
720 // This must not shrink the cache - that breaks the lock-free scheme.
721 void cache_erase_nolock(Class cls)
722 {
723 #if CONFIG_USE_CACHE_LOCK
724 cacheUpdateLock.assertLocked();
725 #else
726 runtimeLock.assertLocked();
727 #endif
728
729 cache_t *cache = getCache(cls);
730
731 mask_t capacity = cache->capacity();
732 if (capacity > 0 && cache->occupied() > 0) {
733 auto oldBuckets = cache->buckets();
734 auto buckets = emptyBucketsForCapacity(capacity);
735 cache->setBucketsAndMask(buckets, capacity - 1); // also clears occupied
736
737 cache_collect_free(oldBuckets, capacity);
738 }
739 }
740
741
742 void cache_delete(Class cls)
743 {
744 #if CONFIG_USE_CACHE_LOCK
745 mutex_locker_t lock(cacheUpdateLock);
746 #else
747 runtimeLock.assertLocked();
748 #endif
749 if (cls->cache.canBeFreed()) {
750 if (PrintCaches) recordDeadCache(cls->cache.capacity());
751 free(cls->cache.buckets());
752 }
753 }
754
755
756 /***********************************************************************
757 * cache collection.
758 **********************************************************************/
759
760 #if !TARGET_OS_WIN32
761
762 // A sentinel (magic value) to report bad thread_get_state status.
763 // Must not be a valid PC.
764 // Must not be zero - thread_get_state() on a new thread returns PC == 0.
765 #define PC_SENTINEL 1
766
767 static uintptr_t _get_pc_for_thread(thread_t thread)
768 #if defined(__i386__)
769 {
770 i386_thread_state_t state;
771 unsigned int count = i386_THREAD_STATE_COUNT;
772 kern_return_t okay = thread_get_state (thread, i386_THREAD_STATE, (thread_state_t)&state, &count);
773 return (okay == KERN_SUCCESS) ? state.__eip : PC_SENTINEL;
774 }
775 #elif defined(__x86_64__)
776 {
777 x86_thread_state64_t state;
778 unsigned int count = x86_THREAD_STATE64_COUNT;
779 kern_return_t okay = thread_get_state (thread, x86_THREAD_STATE64, (thread_state_t)&state, &count);
780 return (okay == KERN_SUCCESS) ? state.__rip : PC_SENTINEL;
781 }
782 #elif defined(__arm__)
783 {
784 arm_thread_state_t state;
785 unsigned int count = ARM_THREAD_STATE_COUNT;
786 kern_return_t okay = thread_get_state (thread, ARM_THREAD_STATE, (thread_state_t)&state, &count);
787 return (okay == KERN_SUCCESS) ? state.__pc : PC_SENTINEL;
788 }
789 #elif defined(__arm64__)
790 {
791 arm_thread_state64_t state;
792 unsigned int count = ARM_THREAD_STATE64_COUNT;
793 kern_return_t okay = thread_get_state (thread, ARM_THREAD_STATE64, (thread_state_t)&state, &count);
794 return (okay == KERN_SUCCESS) ? (uintptr_t)arm_thread_state64_get_pc(state) : PC_SENTINEL;
795 }
796 #else
797 {
798 #error _get_pc_for_thread () not implemented for this architecture
799 }
800 #endif
801
802 #endif
803
804 /***********************************************************************
805 * _collecting_in_critical.
806 * Returns TRUE if some thread is currently executing a cache-reading
807 * function. Collection of cache garbage is not allowed when a cache-
808 * reading function is in progress because it might still be using
809 * the garbage memory.
810 **********************************************************************/
811 #if HAVE_TASK_RESTARTABLE_RANGES
812 #include <kern/restartable.h>
813 #else
814 typedef struct {
815 uint64_t location;
816 unsigned short length;
817 unsigned short recovery_offs;
818 unsigned int flags;
819 } task_restartable_range_t;
820 #endif
821
822 extern "C" task_restartable_range_t objc_restartableRanges[];
823
824 #if HAVE_TASK_RESTARTABLE_RANGES
825 static bool shouldUseRestartableRanges = true;
826 #endif
827
828 void cache_init()
829 {
830 #if HAVE_TASK_RESTARTABLE_RANGES
831 mach_msg_type_number_t count = 0;
832 kern_return_t kr;
833
834 while (objc_restartableRanges[count].location) {
835 count++;
836 }
837
838 kr = task_restartable_ranges_register(mach_task_self(),
839 objc_restartableRanges, count);
840 if (kr == KERN_SUCCESS) return;
841 _objc_fatal("task_restartable_ranges_register failed (result 0x%x: %s)",
842 kr, mach_error_string(kr));
843 #endif // HAVE_TASK_RESTARTABLE_RANGES
844 }
845
846 static int _collecting_in_critical(void)
847 {
848 #if TARGET_OS_WIN32
849 return TRUE;
850 #elif HAVE_TASK_RESTARTABLE_RANGES
851 // Only use restartable ranges if we registered them earlier.
852 if (shouldUseRestartableRanges) {
853 kern_return_t kr = task_restartable_ranges_synchronize(mach_task_self());
854 if (kr == KERN_SUCCESS) return FALSE;
855 _objc_fatal("task_restartable_ranges_synchronize failed (result 0x%x: %s)",
856 kr, mach_error_string(kr));
857 }
858 #endif // !HAVE_TASK_RESTARTABLE_RANGES
859
860 // Fallthrough if we didn't use restartable ranges.
861
862 thread_act_port_array_t threads;
863 unsigned number;
864 unsigned count;
865 kern_return_t ret;
866 int result;
867
868 mach_port_t mythread = pthread_mach_thread_np(objc_thread_self());
869
870 // Get a list of all the threads in the current task
871 #if !DEBUG_TASK_THREADS
872 ret = task_threads(mach_task_self(), &threads, &number);
873 #else
874 ret = objc_task_threads(mach_task_self(), &threads, &number);
875 #endif
876
877 if (ret != KERN_SUCCESS) {
878 // See DEBUG_TASK_THREADS below to help debug this.
879 _objc_fatal("task_threads failed (result 0x%x)\n", ret);
880 }
881
882 // Check whether any thread is in the cache lookup code
883 result = FALSE;
884 for (count = 0; count < number; count++)
885 {
886 int region;
887 uintptr_t pc;
888
889 // Don't bother checking ourselves
890 if (threads[count] == mythread)
891 continue;
892
893 // Find out where thread is executing
894 pc = _get_pc_for_thread (threads[count]);
895
896 // Check for bad status, and if so, assume the worse (can't collect)
897 if (pc == PC_SENTINEL)
898 {
899 result = TRUE;
900 goto done;
901 }
902
903 // Check whether it is in the cache lookup code
904 for (region = 0; objc_restartableRanges[region].location != 0; region++)
905 {
906 uint64_t loc = objc_restartableRanges[region].location;
907 if ((pc > loc) &&
908 (pc - loc < (uint64_t)objc_restartableRanges[region].length))
909 {
910 result = TRUE;
911 goto done;
912 }
913 }
914 }
915
916 done:
917 // Deallocate the port rights for the threads
918 for (count = 0; count < number; count++) {
919 mach_port_deallocate(mach_task_self (), threads[count]);
920 }
921
922 // Deallocate the thread list
923 vm_deallocate (mach_task_self (), (vm_address_t) threads, sizeof(threads[0]) * number);
924
925 // Return our finding
926 return result;
927 }
928
929
930 /***********************************************************************
931 * _garbage_make_room. Ensure that there is enough room for at least
932 * one more ref in the garbage.
933 **********************************************************************/
934
935 // amount of memory represented by all refs in the garbage
936 static size_t garbage_byte_size = 0;
937
938 // do not empty the garbage until garbage_byte_size gets at least this big
939 static size_t garbage_threshold = 32*1024;
940
941 // table of refs to free
942 static bucket_t **garbage_refs = 0;
943
944 // current number of refs in garbage_refs
945 static size_t garbage_count = 0;
946
947 // capacity of current garbage_refs
948 static size_t garbage_max = 0;
949
950 // capacity of initial garbage_refs
951 enum {
952 INIT_GARBAGE_COUNT = 128
953 };
954
955 static void _garbage_make_room(void)
956 {
957 static int first = 1;
958
959 // Create the collection table the first time it is needed
960 if (first)
961 {
962 first = 0;
963 garbage_refs = (bucket_t**)
964 malloc(INIT_GARBAGE_COUNT * sizeof(void *));
965 garbage_max = INIT_GARBAGE_COUNT;
966 }
967
968 // Double the table if it is full
969 else if (garbage_count == garbage_max)
970 {
971 garbage_refs = (bucket_t**)
972 realloc(garbage_refs, garbage_max * 2 * sizeof(void *));
973 garbage_max *= 2;
974 }
975 }
976
977
978 /***********************************************************************
979 * cache_collect_free. Add the specified malloc'd memory to the list
980 * of them to free at some later point.
981 * size is used for the collection threshold. It does not have to be
982 * precisely the block's size.
983 * Cache locks: cacheUpdateLock must be held by the caller.
984 **********************************************************************/
985 static void cache_collect_free(bucket_t *data, mask_t capacity)
986 {
987 #if CONFIG_USE_CACHE_LOCK
988 cacheUpdateLock.assertLocked();
989 #else
990 runtimeLock.assertLocked();
991 #endif
992
993 if (PrintCaches) recordDeadCache(capacity);
994
995 _garbage_make_room ();
996 garbage_byte_size += cache_t::bytesForCapacity(capacity);
997 garbage_refs[garbage_count++] = data;
998 cache_collect(false);
999 }
1000
1001
1002 /***********************************************************************
1003 * cache_collect. Try to free accumulated dead caches.
1004 * collectALot tries harder to free memory.
1005 * Cache locks: cacheUpdateLock must be held by the caller.
1006 **********************************************************************/
1007 void cache_collect(bool collectALot)
1008 {
1009 #if CONFIG_USE_CACHE_LOCK
1010 cacheUpdateLock.assertLocked();
1011 #else
1012 runtimeLock.assertLocked();
1013 #endif
1014
1015 // Done if the garbage is not full
1016 if (garbage_byte_size < garbage_threshold && !collectALot) {
1017 return;
1018 }
1019
1020 // Synchronize collection with objc_msgSend and other cache readers
1021 if (!collectALot) {
1022 if (_collecting_in_critical ()) {
1023 // objc_msgSend (or other cache reader) is currently looking in
1024 // the cache and might still be using some garbage.
1025 if (PrintCaches) {
1026 _objc_inform ("CACHES: not collecting; "
1027 "objc_msgSend in progress");
1028 }
1029 return;
1030 }
1031 }
1032 else {
1033 // No excuses.
1034 while (_collecting_in_critical())
1035 ;
1036 }
1037
1038 // No cache readers in progress - garbage is now deletable
1039
1040 // Log our progress
1041 if (PrintCaches) {
1042 cache_collections++;
1043 _objc_inform ("CACHES: COLLECTING %zu bytes (%zu allocations, %zu collections)", garbage_byte_size, cache_allocations, cache_collections);
1044 }
1045
1046 // Dispose all refs now in the garbage
1047 // Erase each entry so debugging tools don't see stale pointers.
1048 while (garbage_count--) {
1049 auto dead = garbage_refs[garbage_count];
1050 garbage_refs[garbage_count] = nil;
1051 free(dead);
1052 }
1053
1054 // Clear the garbage count and total size indicator
1055 garbage_count = 0;
1056 garbage_byte_size = 0;
1057
1058 if (PrintCaches) {
1059 size_t i;
1060 size_t total_count = 0;
1061 size_t total_size = 0;
1062
1063 for (i = 0; i < countof(cache_counts); i++) {
1064 int count = cache_counts[i];
1065 int slots = 1 << i;
1066 size_t size = count * slots * sizeof(bucket_t);
1067
1068 if (!count) continue;
1069
1070 _objc_inform("CACHES: %4d slots: %4d caches, %6zu bytes",
1071 slots, count, size);
1072
1073 total_count += count;
1074 total_size += size;
1075 }
1076
1077 _objc_inform("CACHES: total: %4zu caches, %6zu bytes",
1078 total_count, total_size);
1079 }
1080 }
1081
1082
1083 /***********************************************************************
1084 * objc_task_threads
1085 * Replacement for task_threads(). Define DEBUG_TASK_THREADS to debug
1086 * crashes when task_threads() is failing.
1087 *
1088 * A failure in task_threads() usually means somebody has botched their
1089 * Mach or MIG traffic. For example, somebody's error handling was wrong
1090 * and they left a message queued on the MIG reply port for task_threads()
1091 * to trip over.
1092 *
1093 * The code below is a modified version of task_threads(). It logs
1094 * the msgh_id of the reply message. The msgh_id can identify the sender
1095 * of the message, which can help pinpoint the faulty code.
1096 * DEBUG_TASK_THREADS also calls collecting_in_critical() during every
1097 * message dispatch, which can increase reproducibility of bugs.
1098 *
1099 * This code can be regenerated by running
1100 * `mig /usr/include/mach/task.defs`.
1101 **********************************************************************/
1102 #if DEBUG_TASK_THREADS
1103
1104 #include <mach/mach.h>
1105 #include <mach/message.h>
1106 #include <mach/mig.h>
1107
1108 #define __MIG_check__Reply__task_subsystem__ 1
1109 #define mig_internal static inline
1110 #define __DeclareSendRpc(a, b)
1111 #define __BeforeSendRpc(a, b)
1112 #define __AfterSendRpc(a, b)
1113 #define msgh_request_port msgh_remote_port
1114 #define msgh_reply_port msgh_local_port
1115
1116 #ifndef __MachMsgErrorWithTimeout
1117 #define __MachMsgErrorWithTimeout(_R_) { \
1118 switch (_R_) { \
1119 case MACH_SEND_INVALID_DATA: \
1120 case MACH_SEND_INVALID_DEST: \
1121 case MACH_SEND_INVALID_HEADER: \
1122 mig_put_reply_port(InP->Head.msgh_reply_port); \
1123 break; \
1124 case MACH_SEND_TIMED_OUT: \
1125 case MACH_RCV_TIMED_OUT: \
1126 default: \
1127 mig_dealloc_reply_port(InP->Head.msgh_reply_port); \
1128 } \
1129 }
1130 #endif /* __MachMsgErrorWithTimeout */
1131
1132 #ifndef __MachMsgErrorWithoutTimeout
1133 #define __MachMsgErrorWithoutTimeout(_R_) { \
1134 switch (_R_) { \
1135 case MACH_SEND_INVALID_DATA: \
1136 case MACH_SEND_INVALID_DEST: \
1137 case MACH_SEND_INVALID_HEADER: \
1138 mig_put_reply_port(InP->Head.msgh_reply_port); \
1139 break; \
1140 default: \
1141 mig_dealloc_reply_port(InP->Head.msgh_reply_port); \
1142 } \
1143 }
1144 #endif /* __MachMsgErrorWithoutTimeout */
1145
1146
1147 #if ( __MigTypeCheck )
1148 #if __MIG_check__Reply__task_subsystem__
1149 #if !defined(__MIG_check__Reply__task_threads_t__defined)
1150 #define __MIG_check__Reply__task_threads_t__defined
1151
1152 mig_internal kern_return_t __MIG_check__Reply__task_threads_t(__Reply__task_threads_t *Out0P)
1153 {
1154
1155 typedef __Reply__task_threads_t __Reply;
1156 boolean_t msgh_simple;
1157 #if __MigTypeCheck
1158 unsigned int msgh_size;
1159 #endif /* __MigTypeCheck */
1160 if (Out0P->Head.msgh_id != 3502) {
1161 if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE)
1162 { return MIG_SERVER_DIED; }
1163 else
1164 { return MIG_REPLY_MISMATCH; }
1165 }
1166
1167 msgh_simple = !(Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX);
1168 #if __MigTypeCheck
1169 msgh_size = Out0P->Head.msgh_size;
1170
1171 if ((msgh_simple || Out0P->msgh_body.msgh_descriptor_count != 1 ||
1172 msgh_size != (mach_msg_size_t)sizeof(__Reply)) &&
1173 (!msgh_simple || msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) ||
1174 ((mig_reply_error_t *)Out0P)->RetCode == KERN_SUCCESS))
1175 { return MIG_TYPE_ERROR ; }
1176 #endif /* __MigTypeCheck */
1177
1178 if (msgh_simple) {
1179 return ((mig_reply_error_t *)Out0P)->RetCode;
1180 }
1181
1182 #if __MigTypeCheck
1183 if (Out0P->act_list.type != MACH_MSG_OOL_PORTS_DESCRIPTOR ||
1184 Out0P->act_list.disposition != 17) {
1185 return MIG_TYPE_ERROR;
1186 }
1187 #endif /* __MigTypeCheck */
1188
1189 return MACH_MSG_SUCCESS;
1190 }
1191 #endif /* !defined(__MIG_check__Reply__task_threads_t__defined) */
1192 #endif /* __MIG_check__Reply__task_subsystem__ */
1193 #endif /* ( __MigTypeCheck ) */
1194
1195
1196 /* Routine task_threads */
1197 static kern_return_t objc_task_threads
1198 (
1199 task_t target_task,
1200 thread_act_array_t *act_list,
1201 mach_msg_type_number_t *act_listCnt
1202 )
1203 {
1204
1205 #ifdef __MigPackStructs
1206 #pragma pack(4)
1207 #endif
1208 typedef struct {
1209 mach_msg_header_t Head;
1210 } Request;
1211 #ifdef __MigPackStructs
1212 #pragma pack()
1213 #endif
1214
1215 #ifdef __MigPackStructs
1216 #pragma pack(4)
1217 #endif
1218 typedef struct {
1219 mach_msg_header_t Head;
1220 /* start of the kernel processed data */
1221 mach_msg_body_t msgh_body;
1222 mach_msg_ool_ports_descriptor_t act_list;
1223 /* end of the kernel processed data */
1224 NDR_record_t NDR;
1225 mach_msg_type_number_t act_listCnt;
1226 mach_msg_trailer_t trailer;
1227 } Reply;
1228 #ifdef __MigPackStructs
1229 #pragma pack()
1230 #endif
1231
1232 #ifdef __MigPackStructs
1233 #pragma pack(4)
1234 #endif
1235 typedef struct {
1236 mach_msg_header_t Head;
1237 /* start of the kernel processed data */
1238 mach_msg_body_t msgh_body;
1239 mach_msg_ool_ports_descriptor_t act_list;
1240 /* end of the kernel processed data */
1241 NDR_record_t NDR;
1242 mach_msg_type_number_t act_listCnt;
1243 } __Reply;
1244 #ifdef __MigPackStructs
1245 #pragma pack()
1246 #endif
1247 /*
1248 * typedef struct {
1249 * mach_msg_header_t Head;
1250 * NDR_record_t NDR;
1251 * kern_return_t RetCode;
1252 * } mig_reply_error_t;
1253 */
1254
1255 union {
1256 Request In;
1257 Reply Out;
1258 } Mess;
1259
1260 Request *InP = &Mess.In;
1261 Reply *Out0P = &Mess.Out;
1262
1263 mach_msg_return_t msg_result;
1264
1265 #ifdef __MIG_check__Reply__task_threads_t__defined
1266 kern_return_t check_result;
1267 #endif /* __MIG_check__Reply__task_threads_t__defined */
1268
1269 __DeclareSendRpc(3402, "task_threads")
1270
1271 InP->Head.msgh_bits =
1272 MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE);
1273 /* msgh_size passed as argument */
1274 InP->Head.msgh_request_port = target_task;
1275 InP->Head.msgh_reply_port = mig_get_reply_port();
1276 InP->Head.msgh_id = 3402;
1277
1278 __BeforeSendRpc(3402, "task_threads")
1279 msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
1280 __AfterSendRpc(3402, "task_threads")
1281 if (msg_result != MACH_MSG_SUCCESS) {
1282 _objc_inform("task_threads received unexpected reply msgh_id 0x%zx",
1283 (size_t)Out0P->Head.msgh_id);
1284 __MachMsgErrorWithoutTimeout(msg_result);
1285 { return msg_result; }
1286 }
1287
1288
1289 #if defined(__MIG_check__Reply__task_threads_t__defined)
1290 check_result = __MIG_check__Reply__task_threads_t((__Reply__task_threads_t *)Out0P);
1291 if (check_result != MACH_MSG_SUCCESS)
1292 { return check_result; }
1293 #endif /* defined(__MIG_check__Reply__task_threads_t__defined) */
1294
1295 *act_list = (thread_act_array_t)(Out0P->act_list.address);
1296 *act_listCnt = Out0P->act_listCnt;
1297
1298 return KERN_SUCCESS;
1299 }
1300
1301 // DEBUG_TASK_THREADS
1302 #endif
1303
1304
1305 // __OBJC2__
1306 #endif