diff options
| author | Richard Brooksby | 2012-09-01 11:40:43 +0100 |
|---|---|---|
| committer | Richard Brooksby | 2012-09-01 11:40:43 +0100 |
| commit | 4fde4e10b29d4779189b81cf9c8a050593514aa3 (patch) | |
| tree | 594dce89e7f1c46ffa568a87e73319a7863f9bad /mps/code/check.h | |
| parent | 89a685f16488555436a7e70782ab3ac6132a59bf (diff) | |
| download | emacs-4fde4e10b29d4779189b81cf9c8a050593514aa3.tar.gz emacs-4fde4e10b29d4779189b81cf9c8a050593514aa3.zip | |
Compiling with a static checking level by default, doubling the speed of the cool variety.
Copied from Perforce
Change: 179157
ServerID: perforce.ravenbrook.com
Diffstat (limited to 'mps/code/check.h')
| -rw-r--r-- | mps/code/check.h | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/mps/code/check.h b/mps/code/check.h index c43dcc1c3d2..63afefad564 100644 --- a/mps/code/check.h +++ b/mps/code/check.h | |||
| @@ -68,12 +68,25 @@ | |||
| 68 | * static variable CheckLevel controls the frequency and detail of | 68 | * static variable CheckLevel controls the frequency and detail of |
| 69 | * consistency checking on structures. | 69 | * consistency checking on structures. |
| 70 | * | 70 | * |
| 71 | * FIXME: This should be initialised from an environment variable and have | 71 | * By default, CHECKLEVEL is defined to a static value in config.h, though |
| 72 | * an interface in mps.h. | 72 | * it can be overridden on the compiler command line, e.g. |
| 73 | * cc -DCHECKLEVEL=CheckLevelSHALLOW ... | ||
| 74 | * | ||
| 75 | * However, if CHECKLEVEL_DYNAMIC is defined we use a variable to control | ||
| 76 | * the level of checking. The run-time overhead for this is quite high | ||
| 77 | * (observed double run-time on amcss when the variable is set to SHALLOW). | ||
| 78 | * CHECKLEVEL_DYNAMIC should be set to the initial level for the variable, | ||
| 79 | * which is in mpm.c. | ||
| 80 | * | ||
| 81 | * In general, it's better to adjust the check level by defining CHECKLEVEL | ||
| 82 | * but this is intended to meet the case where a run-time adjustable | ||
| 83 | * checking level is required -- where recompilation or relinking is | ||
| 84 | * undesirable or impossible. | ||
| 85 | * | ||
| 86 | * FIXME: Should also allow the check level variable to come from an | ||
| 87 | * environment variable. | ||
| 73 | */ | 88 | */ |
| 74 | 89 | ||
| 75 | extern unsigned CheckLevel; | ||
| 76 | |||
| 77 | enum { | 90 | enum { |
| 78 | CheckLevelMINIMAL = 0, /* local sig check only */ | 91 | CheckLevelMINIMAL = 0, /* local sig check only */ |
| 79 | CheckLevelSHALLOW = 1, /* local invariants, */ | 92 | CheckLevelSHALLOW = 1, /* local invariants, */ |
| @@ -83,6 +96,12 @@ enum { | |||
| 83 | /* and recursive down full type checks */ | 96 | /* and recursive down full type checks */ |
| 84 | }; | 97 | }; |
| 85 | 98 | ||
| 99 | #ifdef CHECKLEVEL_DYNAMIC | ||
| 100 | extern unsigned CheckLevel; | ||
| 101 | #undef CHECKLEVEL | ||
| 102 | #define CHECKLEVEL CheckLevel | ||
| 103 | #endif | ||
| 104 | |||
| 86 | 105 | ||
| 87 | /* AVER, AVERT -- MPM assertions | 106 | /* AVER, AVERT -- MPM assertions |
| 88 | * | 107 | * |
| @@ -117,13 +136,13 @@ enum { | |||
| 117 | 136 | ||
| 118 | #define AVER_CRITICAL(cond) \ | 137 | #define AVER_CRITICAL(cond) \ |
| 119 | BEGIN \ | 138 | BEGIN \ |
| 120 | if (CheckLevel != CheckLevelMINIMAL) \ | 139 | if (CHECKLEVEL != CheckLevelMINIMAL) \ |
| 121 | ASSERT(cond, #cond); \ | 140 | ASSERT(cond, #cond); \ |
| 122 | END | 141 | END |
| 123 | 142 | ||
| 124 | #define AVERT_CRITICAL(type, val) \ | 143 | #define AVERT_CRITICAL(type, val) \ |
| 125 | BEGIN \ | 144 | BEGIN \ |
| 126 | if (CheckLevel != CheckLevelMINIMAL) \ | 145 | if (CHECKLEVEL != CheckLevelMINIMAL) \ |
| 127 | ASSERT(type ## Check(val), "TypeCheck " #type ": " #val); \ | 146 | ASSERT(type ## Check(val), "TypeCheck " #type ": " #val); \ |
| 128 | END | 147 | END |
| 129 | 148 | ||
| @@ -166,7 +185,7 @@ enum { | |||
| 166 | 185 | ||
| 167 | /* CHECKS -- Check Signature | 186 | /* CHECKS -- Check Signature |
| 168 | * | 187 | * |
| 169 | * (if CheckLevel == CheckLevelMINIMAL, this is all we check) | 188 | * (if CHECKLEVEL == CheckLevelMINIMAL, this is all we check) |
| 170 | */ | 189 | */ |
| 171 | 190 | ||
| 172 | #if defined(AVER_AND_CHECK_NONE) | 191 | #if defined(AVER_AND_CHECK_NONE) |
| @@ -196,7 +215,7 @@ enum { | |||
| 196 | * - check "up" values which are its "parents" with CHECKU. | 215 | * - check "up" values which are its "parents" with CHECKU. |
| 197 | * | 216 | * |
| 198 | * These various checks will be compiled out or compiled to be controlled | 217 | * These various checks will be compiled out or compiled to be controlled |
| 199 | * by CheckLevel. | 218 | * by CHECKLEVEL. |
| 200 | * | 219 | * |
| 201 | * For example: | 220 | * For example: |
| 202 | * | 221 | * |
| @@ -215,21 +234,16 @@ enum { | |||
| 215 | * children which are Segments, etc. | 234 | * children which are Segments, etc. |
| 216 | * | 235 | * |
| 217 | * The important thing is to have a partial order on types so that recursive | 236 | * The important thing is to have a partial order on types so that recursive |
| 218 | * checking will terminate. When CheckLevel is set to DEEP, checking will | 237 | * checking will terminate. When CHECKLEVEL is set to DEEP, checking will |
| 219 | * recurse into check methods for children, but will only do a shallow | 238 | * recurse into check methods for children, but will only do a shallow |
| 220 | * signature check on parents, avoiding infinite regression. | 239 | * signature check on parents, avoiding infinite regression. |
| 221 | * | ||
| 222 | * FIXME: Switching on every CHECK line doesn't compile very well, because | ||
| 223 | * the compiler can't tell that CheckLevel won't change between function | ||
| 224 | * calls and can't lift out the test. Is there a better arrangement, | ||
| 225 | * perhaps by reading CheckLevel into a local variable? | ||
| 226 | */ | 240 | */ |
| 227 | 241 | ||
| 228 | #if defined(AVER_AND_CHECK_ALL) | 242 | #if defined(AVER_AND_CHECK_ALL) |
| 229 | 243 | ||
| 230 | #define CHECK_BY_LEVEL(minimal, shallow, deep) \ | 244 | #define CHECK_BY_LEVEL(minimal, shallow, deep) \ |
| 231 | BEGIN \ | 245 | BEGIN \ |
| 232 | switch (CheckLevel) { \ | 246 | switch (CHECKLEVEL) { \ |
| 233 | case CheckLevelDEEP: deep; break; \ | 247 | case CheckLevelDEEP: deep; break; \ |
| 234 | case CheckLevelSHALLOW: shallow; break; \ | 248 | case CheckLevelSHALLOW: shallow; break; \ |
| 235 | default: NOTREACHED; /* fall through */ \ | 249 | default: NOTREACHED; /* fall through */ \ |