setjmp_t.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved.
  3. *
  4. * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
  5. * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
  6. *
  7. * Permission is hereby granted to use or copy this program
  8. * for any purpose, provided the above notices are retained on all copies.
  9. * Permission to modify the code and to distribute modified code is granted,
  10. * provided the above notices are retained, and a notice that the code was
  11. * modified is included with the above copyright notice.
  12. */
  13. /* Check whether setjmp actually saves registers in jmp_buf. */
  14. /* If it doesn't, the generic mark_regs code won't work. */
  15. /* Compilers vary as to whether they will put x in a */
  16. /* (callee-save) register without -O. The code is */
  17. /* contrived such that any decent compiler should put x in */
  18. /* a callee-save register with -O. Thus it is */
  19. /* recommended that this be run optimized. (If the machine */
  20. /* has no callee-save registers, then the generic code is */
  21. /* safe, but this will not be noticed by this piece of */
  22. /* code.) This test appears to be far from perfect. */
  23. #include <stdio.h>
  24. #include <setjmp.h>
  25. #include <string.h>
  26. #include "private/gc_priv.h"
  27. #ifdef OS2
  28. /* GETPAGESIZE() is set to getpagesize() by default, but that */
  29. /* doesn't really exist, and the collector doesn't need it. */
  30. #define INCL_DOSFILEMGR
  31. #define INCL_DOSMISC
  32. #define INCL_DOSERRORS
  33. #include <os2.h>
  34. int getpagesize(void)
  35. {
  36. ULONG result[1];
  37. if (DosQuerySysInfo(QSV_PAGE_SIZE, QSV_PAGE_SIZE,
  38. (void *)result, sizeof(ULONG)) != NO_ERROR) {
  39. fprintf(stderr, "DosQuerySysInfo failed\n");
  40. result[0] = 4096;
  41. }
  42. return((int)(result[0]));
  43. }
  44. #elif defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32)
  45. # include <windows.h>
  46. int getpagesize(void)
  47. {
  48. SYSTEM_INFO sysinfo;
  49. GetSystemInfo(&sysinfo);
  50. return sysinfo.dwPageSize;
  51. }
  52. #endif
  53. struct a_s {
  54. char a_a;
  55. char * a_b;
  56. } a;
  57. word nested_sp(void)
  58. {
  59. # if GC_GNUC_PREREQ(4, 0)
  60. return (word)__builtin_frame_address(0);
  61. # else
  62. volatile word sp;
  63. sp = (word)(&sp);
  64. return sp;
  65. # endif
  66. }
  67. /* To prevent nested_sp inlining. */
  68. word (*volatile nested_sp_fn)(void) = nested_sp;
  69. int g(int x);
  70. int main(void)
  71. {
  72. volatile word sp;
  73. unsigned ps = GETPAGESIZE();
  74. JMP_BUF b;
  75. register int x = (int)strlen("a"); /* 1, slightly disguised */
  76. static volatile int y = 0;
  77. sp = (word)(&sp);
  78. printf("This appears to be a %s running %s\n", MACH_TYPE, OS_TYPE);
  79. # if defined(CPPCHECK)
  80. (void)nested_sp(); /* to workaround a bug in cppcheck */
  81. # endif
  82. if (nested_sp_fn() < sp) {
  83. printf("Stack appears to grow down, which is the default.\n");
  84. printf("A good guess for STACKBOTTOM on this machine is 0x%lx.\n",
  85. ((unsigned long)sp + ps) & ~(ps-1));
  86. } else {
  87. printf("Stack appears to grow up.\n");
  88. printf("Define STACK_GROWS_UP in gc_private.h\n");
  89. printf("A good guess for STACKBOTTOM on this machine is 0x%lx.\n",
  90. ((unsigned long)sp + ps) & ~(ps-1));
  91. }
  92. printf("Note that this may vary between machines of ostensibly\n");
  93. printf("the same architecture (e.g. Sun 3/50s and 3/80s).\n");
  94. printf("On many machines the value is not fixed.\n");
  95. printf("A good guess for ALIGNMENT on this machine is %lu.\n",
  96. (unsigned long)((word)(&(a.a_b)) - (word)(&a)));
  97. printf("The following is a very dubious test of one root marking"
  98. " strategy.\n");
  99. printf("Results may not be accurate/useful:\n");
  100. /* Encourage the compiler to keep x in a callee-save register */
  101. x = 2*x-1;
  102. printf("\n");
  103. x = 2*x-1;
  104. (void)SETJMP(b);
  105. if (y == 1) {
  106. if (x == 2) {
  107. printf("Setjmp-based generic mark_regs code probably won't work.\n");
  108. printf("But we rarely try that anymore. If you have getcontect()\n");
  109. printf("this probably doesn't matter.\n");
  110. } else if (x == 1) {
  111. printf("Setjmp-based register marking code may work.\n");
  112. } else {
  113. printf("Very strange setjmp implementation.\n");
  114. }
  115. }
  116. y++;
  117. x = 2;
  118. if (y == 1) LONGJMP(b, 1);
  119. printf("Some GC internal configuration stuff: \n");
  120. printf("\tWORDSZ = %lu, ALIGNMENT = %d, GC_GRANULE_BYTES = %d\n",
  121. (unsigned long)WORDSZ, ALIGNMENT, GC_GRANULE_BYTES);
  122. printf("\tUsing one mark ");
  123. # if defined(USE_MARK_BYTES)
  124. printf("byte");
  125. # else
  126. printf("bit");
  127. # endif
  128. printf(" per ");
  129. # if defined(MARK_BIT_PER_OBJ)
  130. printf("object.\n");
  131. # elif defined(MARK_BIT_PER_GRANULE)
  132. printf("granule.\n");
  133. # endif
  134. # ifdef THREAD_LOCAL_ALLOC
  135. printf("Thread local allocation enabled.\n");
  136. # endif
  137. # ifdef PARALLEL_MARK
  138. printf("Parallel marking enabled.\n");
  139. # endif
  140. (void)g(x);
  141. return(0);
  142. }
  143. int g(int x)
  144. {
  145. return(x);
  146. }