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 | |
| 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
| -rw-r--r-- | mps/code/check.h | 44 | ||||
| -rw-r--r-- | mps/code/config.h | 24 | ||||
| -rw-r--r-- | mps/code/mpm.c | 6 |
3 files changed, 45 insertions, 29 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 */ \ |
diff --git a/mps/code/config.h b/mps/code/config.h index 86b3a22b610..15c30b6e5e0 100644 --- a/mps/code/config.h +++ b/mps/code/config.h | |||
| @@ -35,7 +35,6 @@ | |||
| 35 | 35 | ||
| 36 | #if defined(CONFIG_VAR_WE) /* White-hot variety */ | 36 | #if defined(CONFIG_VAR_WE) /* White-hot variety */ |
| 37 | /* no asserts */ | 37 | /* no asserts */ |
| 38 | /* ... so CHECKLEVEL_INITIAL is irrelevant */ | ||
| 39 | /* no statistic meters */ | 38 | /* no statistic meters */ |
| 40 | /* no telemetry log events */ | 39 | /* no telemetry log events */ |
| 41 | 40 | ||
| @@ -49,7 +48,9 @@ | |||
| 49 | 48 | ||
| 50 | #elif defined(CONFIG_VAR_HE) /* Hot variety */ | 49 | #elif defined(CONFIG_VAR_HE) /* Hot variety */ |
| 51 | #define CONFIG_ASSERT | 50 | #define CONFIG_ASSERT |
| 52 | #define CHECKLEVEL_INITIAL CheckLevelMINIMAL | 51 | #ifndef CHECKLEVEL |
| 52 | #define CHECKLEVEL CheckLevelMINIMAL | ||
| 53 | #endif | ||
| 53 | /* no statistic meters */ | 54 | /* no statistic meters */ |
| 54 | /* no telemetry log events */ | 55 | /* no telemetry log events */ |
| 55 | 56 | ||
| @@ -63,7 +64,9 @@ | |||
| 63 | 64 | ||
| 64 | #elif defined(CONFIG_VAR_DI) /* Diagnostic variety */ | 65 | #elif defined(CONFIG_VAR_DI) /* Diagnostic variety */ |
| 65 | #define CONFIG_ASSERT | 66 | #define CONFIG_ASSERT |
| 66 | #define CHECKLEVEL_INITIAL CheckLevelMINIMAL | 67 | #ifndef CHECKLEVEL |
| 68 | #define CHECKLEVEL CheckLevelMINIMAL | ||
| 69 | #endif | ||
| 67 | #define CONFIG_STATS | 70 | #define CONFIG_STATS |
| 68 | /* For diagnostics, choose a DIAG_WITH_... output method. | 71 | /* For diagnostics, choose a DIAG_WITH_... output method. |
| 69 | * (We need to choose because the DIAG output system is under | 72 | * (We need to choose because the DIAG output system is under |
| @@ -85,8 +88,10 @@ | |||
| 85 | #elif defined(CONFIG_VAR_CI) /* Cool variety */ | 88 | #elif defined(CONFIG_VAR_CI) /* Cool variety */ |
| 86 | #define CONFIG_ASSERT | 89 | #define CONFIG_ASSERT |
| 87 | #define CONFIG_ASSERT_ALL | 90 | #define CONFIG_ASSERT_ALL |
| 88 | /* ... let PRODUCT determine CHECKLEVEL_INITIAL */ | ||
| 89 | #define CONFIG_STATS | 91 | #define CONFIG_STATS |
| 92 | #ifndef CHECKLEVEL | ||
| 93 | #define CHECKLEVEL CheckLevelSHALLOW | ||
| 94 | #endif | ||
| 90 | /* no telemetry log events */ | 95 | /* no telemetry log events */ |
| 91 | 96 | ||
| 92 | 97 | ||
| @@ -100,7 +105,9 @@ | |||
| 100 | #elif defined(CONFIG_VAR_TI) /* Telemetry, Internal; variety.ti */ | 105 | #elif defined(CONFIG_VAR_TI) /* Telemetry, Internal; variety.ti */ |
| 101 | #define CONFIG_ASSERT | 106 | #define CONFIG_ASSERT |
| 102 | #define CONFIG_ASSERT_ALL | 107 | #define CONFIG_ASSERT_ALL |
| 103 | /* ... let PRODUCT determine CHECKLEVEL_INITIAL */ | 108 | #ifndef CHECKLEVEL |
| 109 | #define CHECKLEVEL CheckLevelSHALLOW | ||
| 110 | #endif | ||
| 104 | #define CONFIG_STATS | 111 | #define CONFIG_STATS |
| 105 | #define CONFIG_LOG | 112 | #define CONFIG_LOG |
| 106 | 113 | ||
| @@ -400,13 +407,6 @@ | |||
| 400 | */ | 407 | */ |
| 401 | #define ARENA_SIZE ((Size)1<<30) | 408 | #define ARENA_SIZE ((Size)1<<30) |
| 402 | 409 | ||
| 403 | /* if CHECKLEVEL_INITIAL hasn't been defined already (e.g. by a variety, or | ||
| 404 | * in a makefile), take the value from the product. */ | ||
| 405 | |||
| 406 | #ifndef CHECKLEVEL_INITIAL | ||
| 407 | #define CHECKLEVEL_INITIAL PROD_CHECKLEVEL_INITIAL | ||
| 408 | #endif | ||
| 409 | |||
| 410 | 410 | ||
| 411 | /* Dongle configuration */ | 411 | /* Dongle configuration */ |
| 412 | 412 | ||
diff --git a/mps/code/mpm.c b/mps/code/mpm.c index 4f9af3f888c..f287f2cf964 100644 --- a/mps/code/mpm.c +++ b/mps/code/mpm.c | |||
| @@ -23,10 +23,12 @@ SRCID(mpm, "$Id$"); | |||
| 23 | 23 | ||
| 24 | /* CheckLevel -- Control check level | 24 | /* CheckLevel -- Control check level |
| 25 | * | 25 | * |
| 26 | * This controls the behaviour of Check methods (see impl.h.check). | 26 | * This controls the behaviour of Check methods (see check.h). |
| 27 | */ | 27 | */ |
| 28 | 28 | ||
| 29 | unsigned CheckLevel = CHECKLEVEL_INITIAL; | 29 | #ifdef CHECKLEVEL_DYNAMIC |
| 30 | unsigned CheckLevel = CHECKLEVEL_DYNAMIC; | ||
| 31 | #endif | ||
| 30 | 32 | ||
| 31 | 33 | ||
| 32 | /* MPMCheck -- test MPM assumptions */ | 34 | /* MPMCheck -- test MPM assumptions */ |