aboutsummaryrefslogtreecommitdiffstats
path: root/mps/code
diff options
context:
space:
mode:
authorRichard Brooksby2012-09-01 11:40:43 +0100
committerRichard Brooksby2012-09-01 11:40:43 +0100
commit4fde4e10b29d4779189b81cf9c8a050593514aa3 (patch)
tree594dce89e7f1c46ffa568a87e73319a7863f9bad /mps/code
parent89a685f16488555436a7e70782ab3ac6132a59bf (diff)
downloademacs-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')
-rw-r--r--mps/code/check.h44
-rw-r--r--mps/code/config.h24
-rw-r--r--mps/code/mpm.c6
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
75extern unsigned CheckLevel;
76
77enum { 90enum {
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
100extern 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
29unsigned CheckLevel = CHECKLEVEL_INITIAL; 29#ifdef CHECKLEVEL_DYNAMIC
30unsigned CheckLevel = CHECKLEVEL_DYNAMIC;
31#endif
30 32
31 33
32/* MPMCheck -- test MPM assumptions */ 34/* MPMCheck -- test MPM assumptions */