rr-sidetable.m 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. // TEST_CFLAGS -framework Foundation
  2. // TEST_CONFIG MEM=mrc ARCH=x86_64
  3. // Stress-test nonpointer isa's side table retain count transfers.
  4. // x86_64 only. arm64's side table limit is high enough that bugs
  5. // are harder to reproduce.
  6. #include "test.h"
  7. #import <Foundation/Foundation.h>
  8. #define OBJECTS 1
  9. #define LOOPS 256
  10. #define THREADS 16
  11. #if __x86_64__
  12. # define RC_HALF (1ULL<<7)
  13. #else
  14. # error sorry
  15. #endif
  16. #define RC_DELTA RC_HALF
  17. static bool Deallocated = false;
  18. @interface Deallocator : NSObject @end
  19. @implementation Deallocator
  20. -(void)dealloc {
  21. Deallocated = true;
  22. [super dealloc];
  23. }
  24. @end
  25. // This is global to avoid extra retains by the dispatch block objects.
  26. static Deallocator *obj;
  27. int main() {
  28. dispatch_queue_t queue =
  29. dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
  30. for (size_t i = 0; i < OBJECTS; i++) {
  31. obj = [Deallocator new];
  32. dispatch_apply(THREADS, queue, ^(size_t i __unused) {
  33. for (size_t a = 0; a < LOOPS; a++) {
  34. for (size_t b = 0; b < RC_DELTA; b++) {
  35. [obj retain];
  36. }
  37. for (size_t b = 0; b < RC_DELTA; b++) {
  38. [obj release];
  39. }
  40. }
  41. });
  42. testassert(!Deallocated);
  43. [obj release];
  44. testassert(Deallocated);
  45. Deallocated = false;
  46. }
  47. succeed(__FILE__);
  48. }