msgSend-performance.m 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. // TEST_CONFIG
  2. #include "test.h"
  3. #include "testroot.i"
  4. #include <simd/simd.h>
  5. #if defined(__arm__)
  6. // rdar://8331406
  7. # define ALIGN_()
  8. #else
  9. # define ALIGN_() asm(".align 4");
  10. #endif
  11. @interface Super : TestRoot @end
  12. @implementation Super
  13. -(void)voidret_nop
  14. {
  15. return;
  16. }
  17. -(void)voidret_nop2
  18. {
  19. return;
  20. }
  21. -(id)idret_nop
  22. {
  23. return nil;
  24. }
  25. -(long long)llret_nop
  26. {
  27. return 0;
  28. }
  29. -(struct stret)stret_nop
  30. {
  31. return STRET_RESULT;
  32. }
  33. -(double)fpret_nop
  34. {
  35. return 0;
  36. }
  37. -(long double)lfpret_nop
  38. {
  39. return 0;
  40. }
  41. -(vector_ulong2)vecret_nop
  42. {
  43. return (vector_ulong2){0x1234567890abcdefULL, 0xfedcba0987654321ULL};
  44. }
  45. @end
  46. @interface Sub : Super @end
  47. @implementation Sub @end
  48. int main()
  49. {
  50. // cached message performance
  51. // catches failure to cache or (abi=2) failure to fixup (#5584187)
  52. // fixme unless they all fail
  53. uint64_t startTime;
  54. uint64_t totalTime;
  55. uint64_t targetTime;
  56. Sub *sub = [Sub new];
  57. // fill cache first
  58. [sub voidret_nop];
  59. [sub voidret_nop2];
  60. [sub llret_nop];
  61. [sub stret_nop];
  62. [sub fpret_nop];
  63. [sub lfpret_nop];
  64. [sub vecret_nop];
  65. [sub voidret_nop];
  66. [sub voidret_nop2];
  67. [sub llret_nop];
  68. [sub stret_nop];
  69. [sub fpret_nop];
  70. [sub lfpret_nop];
  71. [sub vecret_nop];
  72. [sub voidret_nop];
  73. [sub voidret_nop2];
  74. [sub llret_nop];
  75. [sub stret_nop];
  76. [sub fpret_nop];
  77. [sub lfpret_nop];
  78. [sub vecret_nop];
  79. // Some of these times have high variance on some compilers.
  80. // The errors we're trying to catch should be catastrophically slow,
  81. // so the margins here are generous to avoid false failures.
  82. // Use voidret because id return is too slow for perf test with ARC.
  83. // Pick smallest of voidret_nop and voidret_nop2 time
  84. // in the hopes that one of them didn't collide in the method cache.
  85. // ALIGN_ matches loop alignment to make -O0 work
  86. #define COUNT 1000000
  87. startTime = mach_absolute_time();
  88. ALIGN_();
  89. for (int i = 0; i < COUNT; i++) {
  90. [sub voidret_nop];
  91. }
  92. totalTime = mach_absolute_time() - startTime;
  93. testprintf("time: voidret %llu\n", totalTime);
  94. targetTime = totalTime;
  95. startTime = mach_absolute_time();
  96. ALIGN_();
  97. for (int i = 0; i < COUNT; i++) {
  98. [sub voidret_nop2];
  99. }
  100. totalTime = mach_absolute_time() - startTime;
  101. testprintf("time: voidret2 %llu\n", totalTime);
  102. if (totalTime < targetTime) targetTime = totalTime;
  103. startTime = mach_absolute_time();
  104. ALIGN_();
  105. for (int i = 0; i < COUNT; i++) {
  106. [sub llret_nop];
  107. }
  108. totalTime = mach_absolute_time() - startTime;
  109. timecheck("llret ", totalTime, targetTime * 0.65, targetTime * 2.0);
  110. startTime = mach_absolute_time();
  111. ALIGN_();
  112. for (int i = 0; i < COUNT; i++) {
  113. [sub stret_nop];
  114. }
  115. totalTime = mach_absolute_time() - startTime;
  116. timecheck("stret ", totalTime, targetTime * 0.65, targetTime * 5.0);
  117. startTime = mach_absolute_time();
  118. ALIGN_();
  119. for (int i = 0; i < COUNT; i++) {
  120. [sub fpret_nop];
  121. }
  122. totalTime = mach_absolute_time() - startTime;
  123. timecheck("fpret ", totalTime, targetTime * 0.65, targetTime * 4.0);
  124. startTime = mach_absolute_time();
  125. ALIGN_();
  126. for (int i = 0; i < COUNT; i++) {
  127. [sub lfpret_nop];
  128. }
  129. totalTime = mach_absolute_time() - startTime;
  130. timecheck("lfpret", totalTime, targetTime * 0.65, targetTime * 4.0);
  131. startTime = mach_absolute_time();
  132. ALIGN_();
  133. for (int i = 0; i < COUNT; i++) {
  134. [sub vecret_nop];
  135. }
  136. totalTime = mach_absolute_time() - startTime;
  137. timecheck("vecret", totalTime, targetTime * 0.65, targetTime * 4.0);
  138. succeed(__FILE__);
  139. }