• R/O
  • SSH
  • HTTPS

bif-c: コミット


コミットメタ情報

リビジョン54 (tree)
日時2017-05-31 12:37:39
作者reiisi

ログメッセージ

Correcting a race condition and de-optimizing double integers.
The race/test order problem was left over from the fig 6800 model.
The doubles thing is just trying too hard.
Optimization is in the Forth you metacompile using this.

変更サマリ

差分

--- trunk/bif_eval.c (revision 53)
+++ trunk/bif_eval.c (revision 54)
@@ -518,13 +518,20 @@
518518 Compile n as a literal, if compiling.
519519 */
520520 void LITER(void)
521-{ LITERS; /* This is a race condition. Also, want to use the same code as comma. */
521+{
522+ LITERS; /* Is this well enough defined? */
523+ /* There may be race conditions. Use comma for full allocation checks. */
524+ ( * --SP ).definitionp = &hLIT;
525+ COMMA();
526+ COMMA();
527+/*
528+ HERERR( BYTESPERCELL + BYTESPERCELL );;
522529 { cell_u * allocation = UP.task->dictionaryAllocationPointer.cellp;
523530 ( * allocation++ ).definitionp = &hLIT;
524531 ( * allocation++ ) = * SP++;
525532 UP.task->dictionaryAllocationPointer.cellp = allocation;
526533 }
527- HERERR;
534+*/
528535 }
529536
530537
@@ -579,7 +586,11 @@
579586 Compile d as a double literal, if compiling.
580587 */
581588 void DLITER(void)
582-{ LITERS;
589+{ LITERS; /* Is this well enough defined? */
590+#if defined UNSAFE_DOUBLE_OPTIMIZING
591+// JMR201705301113: This is probably not a good idea.
592+// The compiler is not our friend.
593+ HERERR( BYTESPERCELL + BYTESPERDOUBLE );
583594 { cell_u * allocation = UP.task->dictionaryAllocationPointer.cellp;
584595 dblnatural_t * dallocation;
585596 dblnatural_t * stack = (dblnatural_t *) ( (char *) SP );
@@ -592,7 +603,14 @@
592603 */
593604 UP.task->dictionaryAllocationPointer.cellp = (cell_u *) ( ( char *) dallocation );
594605 }
595- HERERR;
606+#else /* Just do it the safe way. This interpreter is not intended to be that fast. */
607+ /* There may be race conditions. Use comma for full allocation checks. */
608+ ( * --SP ).definitionp = &hDLIT;
609+ COMMA();
610+ SWAP();
611+ COMMA();
612+ COMMA();
613+#endif /* defined UNSAFE_DOUBLE_OPTIMIZING */
596614 }
597615
598616
--- trunk/bif_vm.c (revision 53)
+++ trunk/bif_vm.c (revision 54)
@@ -611,20 +611,24 @@
611611 void DLIT(void)
612612 {
613613 /* Handled by the type.
614+// JMR201705301113: But this is probably not a good idea, anyway.
615+// The compiler is not our friend.
614616 // #if !defined MANUFACTURED_DOUBLE && !defined LOW_C_CELL_FIRST // * FORTH CPU byte order for doubles.
615617 */
618+#if defined UNSAFE_DOUBLE_OPTIMIZING
616619 dblnatural_t * stack = (dblnatural_t *) ( (char *) SP );
617620 dblnatural_t * list = (dblnatural_t *) ( (char *) IP );
618621 * --stack = * list++; /* This is closer to optimized, anyway. */
619622 SP = (cell_u *) ( (char *) stack );
620623 IP = (cell_u *) ( (char *) list );
621-/* #else // * defined MANUFACTURED_DOUBLE || defined LOW_C_CELL_FIRST * /
622-// SP -= 2;
623-// SP[ 0 ] = IP[ 0 ]; // * Pay attention! * /
624-// SP[ 1 ] = IP[ 1 ]; // * Just pushing twice from the list would invert the half-double-cells. * /
625-// IP += 2;
626-// #endif // * !defined MANUFACTURED_DOUBLE && !defined LOW_C_CELL_FIRST
627-*/
624+#else /* Just do it the safe way. This interpreter is not intended to be that fast. */
625+/* #else // * defined MANUFACTURED_DOUBLE || defined LOW_C_CELL_FIRST */
626+ SP -= 2;
627+ SP[ 0 ] = IP[ 0 ]; // * Pay attention! * /
628+ SP[ 1 ] = IP[ 1 ]; // * Just pushing twice from the list would invert the half-double-cells. * /
629+ IP += 2;
630+/* #endif // * !defined MANUFACTURED_DOUBLE && !defined LOW_C_CELL_FIRST */
631+#endif /* defined UNSAFE_DOUBLE_OPTIMIZING */
628632 }
629633
630634
--- trunk/bifst_a.c (revision 53)
+++ trunk/bifst_a.c (revision 54)
@@ -197,7 +197,7 @@
197197 { MSG_INTERNAL_STRINGS }, /* initial disk on-line flag */
198198 /* Either I change the fence to see a flag or a link, or I copy the headers into memoryImage. */
199199 { (natural_t) 0 /* allocatable area; was FOLLOW - 1 */ }, /* FENCE for FORGET */
200- { (natural_t) 0 /* was FOLLOW */ }, /* initial allocation pointer. */
200+ { (natural_t) ALLOC_BUMPER /* was FOLLOW */ }, /* initial allocation pointer. */
201201 { (natural_t) &hBIF.parameterLink[ 0 ] }, /* initial context root, both contexts. */
202202 { (natural_t) SZPAD }, /* numeric conversion buffer */
203203 { (natural_t) SZWPAD + SZHASH }, /* word buffer */
--- trunk/bifst_a.h (revision 53)
+++ trunk/bifst_a.h (revision 54)
@@ -23,6 +23,10 @@
2323 #include "bif6_a.h"
2424
2525
26+#define ALLOC_BUMPER ( 16 * BYTESPERCELL )
27+
28+#define OBJECTS_IN_MEMORY 12 /* Estimate -- eyeball count + 4 */
29+
2630 /*
2731 00000010 * Start up routines for BIF
2832 00020 * BIF Copyright 1989 Joel Matthew Rees (see BIF/ASM)
@@ -38,7 +42,7 @@
3842 ** Right now, I'm grabbing a block of RAM and allocating backwards,
3943 ** the way I did it on the 6809.
4044 */
41-#define ILIMmin ( 2048 * BYTESPERCELL )
45+#define ILIMmin ( 2048 * BYTESPERCELL + OBJECTS_IN_MEMORY * ALLOC_BUMPER )
4246 #define ILIM 0x10000L /* Was the bottom half of memory in the Color Computer, 0x8000, but we need space. */
4347 #if defined STATIC_MEMORYIMAGE
4448 extern byte_t memoryImage[ ILIM ]; /* So I can FORGET like I did in BIF-6809. */
@@ -61,30 +65,31 @@
6165 /* The first control word contains the dirty buffers flag. */
6266 #define BUFF_DIRTY_FLAG CELL_HIGH_BIT
6367 #define SZBUFF ( BCT * ( BWID + BUFF_CTRL_WID ) )
64-#define IBUFF ( ILIM - SZBUFF ) /* Not using IBUFF any more. */
68+#define IBUFF ( ILIM - ALLOC_BUMPER - SZBUFF ) /* IBUFF dynamic now. */
6569
6670 /* 00120 IPAD EQU IBUFF-TWID max */
6771 #define SZPAD TWID
68-#define IPAD ( IBUFF - SZPAD ) /* IPAD not used any more. */
72+#define IPAD ( IBUFF - ALLOC_BUMPER - SZPAD ) /* IPAD dynamic now. */
6973
7074 /* 00130 IHASH EQU IPAD-34 */
7175 /* I don't remember what the 34 is. Wait, max binary digits of a double, plus two characters? */
7276 #define SZHASH 80
73-#define IHASH ( IPAD - SZHASH ) /* Numeric formatting buffer, I think. */
77+#define IHASH ( IPAD - ALLOC_BUMPER - SZHASH ) /* Numeric formatting buffer, I think. Dynamic now */
7478
7579 /* 00140 IWPAD EQU IHASH-NLMASK-2 */
7680 #define SZWPAD ( NameLength_k - 8 )
77-#define IWPAD ( IHASH - SZWPAD ) /* The word pad string parsing buffer. IWPAD not used any more. */
81+#define IWPAD ( IHASH - ALLOC_BUMPER - SZWPAD ) /* The word pad string parsing buffer. IWPAD dynamic now. */
7882
7983 /* 00150 ITIB EQU IWPAD-TWID */
8084 #define SZTIB TWID
81-#define ITIB ( IWPAD - SZTIB ) /* Base of terminal input buffer. ITIB not used any more. */
85+#define ITIB ( IWPAD - ALLOC_BUMPER - SZTIB ) /* Base of terminal input buffer. ITIB dynamic now. */
8286
8387 /* 00160 IUSER EQU ITIB-UEND */
8488 #define SZUSERTBLS ( 4 * UEND ) /* Room for 4 tasks, just for fun? */
85-#define IUSER ( ITIB - SZUSERTBLS ) /* Base of user structure. IUSER not used any more. */
89+#define IUSER ( ITIB - ALLOC_BUMPER - SZUSERTBLS ) /* Base of user structure. IUSER dynamic now. */
8690
8791 #define STACK_BUMPER_HOLE 2 /* and one more than the original, for good measure. */
92+/* See also, ALLOC_BUMPER */
8893 #define CONTROL_STACK_SIZE 256 /* At least twice the original, since C is a bit bulky. */
8994
9095 #if CONTROL_STACK_SIZE < 128
@@ -96,11 +101,11 @@
96101 #endif
97102
98103 /* 00170 IRP0 EQU IUSER-2 */
99-#define STACKGAP ( STACK_BUMPER_HOLE * sizeof (cell_u) )
100-#define IRP0 ( IUSER - STACKGAP ) /* With the crash buffer hole. IRP0 not used any more. */
104+#define STACKGAP ( STACK_BUMPER_HOLE * sizeof (cell_u) + ALLOC_BUMPER )
105+#define IRP0 ( IUSER - STACKGAP ) /* With the crash buffer hole. IRP0 dynamic now. */
101106
102107 /* 00180 ISP0 EQU IRP0-258 */
103-#define ISP0 ( IRP0 - ( CONTROL_STACK_SIZE + STACK_BUMPER_HOLE ) * sizeof (cell_u) ) /* Again, crash buffer. */
108+#define ISP0 ( IRP0 - ( CONTROL_STACK_SIZE + STACK_BUMPER_HOLE ) * sizeof (cell_u) + ALLOC_BUMPER ) /* Again, crash buffer. */
104109
105110 /* The dictionary heap grows from the bottom up.
106111 */
--- trunk/bif2b_a.c (revision 53)
+++ trunk/bif2b_a.c (revision 54)
@@ -56,8 +56,9 @@
5656 ** HERERR and ALLERR are converted to macros.
5757 */
5858 void HERE(void)
59-{ * --SP = UP.task->dictionaryAllocationPointer;
60- HERERR;
59+{
60+ HERERR( 0 ); /* check first, to make absolutely sure there is no race. */
61+ * --SP = UP.task->dictionaryAllocationPointer;
6162 }
6263
6364
@@ -97,8 +98,9 @@
9798 // That should be picked up in HERERR, anyway,
9899 // but does it make sense to check separately here for real nonsense?
99100 */
101+ /* Need to address the problems of misalligned allocation, but not here. */
102+ HERERR( ( * SP ).integer ); /* Now checking first, to eliminate race condition. */
100103 UP.task->dictionaryAllocationPointer.bytep += ( * SP++ ).integer;
101- HERERR;
102104 }
103105
104106
@@ -132,6 +134,7 @@
132134 { (natural_t) &hSTORE }
133135 // But then, what about HERERR?
134136 // -- thus, the other side of the switching modes on the fly issue.
137+ // JMR20105301017: Modes partially solved?
135138 }
136139 */
137140 };
@@ -146,12 +149,13 @@
146149 05375 BRA HERERR
147150 05380 *
148151 */
149-void COMMA(void) /* Needs to be refactored, and needs to check first. */
152+void COMMA(void) /* Needs to be refactored, now checking first. */
150153 { cell_u * here = UP.task->dictionaryAllocationPointer.cellp;
154+ /* Need to address the problems of misalligned cells. */
155+ ALIGNERR( BYTESPERCELL );
156+ HERERR( BYTESPERCELL );
151157 * here++ = * SP++;
152158 UP.task->dictionaryAllocationPointer.cellp = here; /* COMSTO is actually HERE_UPDATE */
153- /* Updating HERE is done out of order. Race condition. */
154- HERERR;
155159 }
156160
157161
@@ -177,14 +181,15 @@
177181 05375 BRA HERERR
178182 05380 *
179183 */
180-void DCOMMA(void) /* Needs to be refactored, and needs to check first. */
184+void DCOMMA(void) /* Needs to be refactored, now checking first. */
181185 { dblnatural_t * here = UP.task->dictionaryAllocationPointer.doublep;
182186 dblnatural_t * stack = (dblnatural_t *) ( (char *) SP );
187+ /* Need to address the problems of misalligned doubles. */
188+ ALIGNERR( BYTESPERCELL );
189+ HERERR( BYTESPERDOUBLE );
183190 * here++ = * stack++;
184191 SP = (cell_u *) ( (char *) stack );
185192 UP.task->dictionaryAllocationPointer.doublep = here;
186- /* Updating HERE is done out of order. Race condition. */
187- HERERR;
188193 }
189194
190195
@@ -220,10 +225,10 @@
220225 void CCOMMA( void ) /* C, needs a FILL2BOUND and something to deal with length slop. Instead, STRING, perhaps? */
221226 {
222227 byte_t * here = UP.task->dictionaryAllocationPointer.bytep;
228+ HERERR( 1 );
223229 * here++ = (byte_t) SP[ 0 ].integer;
224230 UP.task->dictionaryAllocationPointer.bytep = here; /* Seems meaningless to make this wrong code a macro. */
225231 ++SP;
226- HERERR;
227232 }
228233
229234
@@ -241,10 +246,10 @@
241246 void OCOMMA( void ) /* Well, this is the FILL2BOUND. */
242247 {
243248 byte_t * here = UP.task->dictionaryAllocationPointer.bytep;
249+ HERERR( sizeof (cell_u) - 1 ); /* Be sloppy but safe. */
244250 while ( ( ( (natural_t) here ) & ( sizeof (cell_u) - 1 ) ) != 0 )
245251 * here++ = (byte_t) 0;
246252 UP.task->dictionaryAllocationPointer.bytep = here; /* Seems meaningless to make this wrong code a macro. */
247- HERERR;
248253 }
249254
250255
--- trunk/bif6_a.c (revision 53)
+++ trunk/bif6_a.c (revision 54)
@@ -562,7 +562,7 @@
562562 void QUERY(void)
563563 { UP.task->bufferInputOffset.integer = 0;
564564 ( * --SP ) = UP.task->terminalInputBuffer;
565- ( * --SP ).integer = TWID;
565+ ( * --SP ).integer = TWID; /* Shouldn't this be a per-USER constant? */
566566 EXPECT();
567567 }
568568
--- trunk/bif2b_a.h (revision 53)
+++ trunk/bif2b_a.h (revision 54)
@@ -18,9 +18,6 @@
1818
1919 #include "bif5b_a.h" /* for mERROR */
2020
21-
22-extern definition_header_s hHERE;
23-extern void HERE(void);
2421 /*
2522 05100 HERE LDX <UP
2623 05110 LDD UDP,X
@@ -35,14 +32,28 @@
3532 05140 *
3633 ** HERERR and ALLERR are converted to macros.
3734 */
38-
39-#define HERERR /* Check allocation limits. */ \
40-{ if ( UP.task->dictionaryAllocationPointer.cellp + 10 >= SP ) /* Probably want to buffer this, really. */ \
35+/* JMR201705300920: Fixing race condition and potential pointer beyond bounds calculation.
36+*/
37+#define HERERR( p ) /* Check allocation limits. */ \
38+{ if ( SP - UP.task->dictionaryAllocationPointer.cellp <= (p) + ALLOC_BUMPER ) /* Keep a bumper zone. */ \
4139 ALLERR; \
4240 }
4341
4442 #define ALLERR mERROR( 2 ); /* Report allocation errors. */
4543
44+/* For the present, and probably for the long term,
45+// doubles are handled one cell at a time.
46+// Depends on two's complement and power of two size
47+*/
48+#define ALIGNERR( size ) /* Check whether HERE is safe to store this. */ \
49+{ if ( UP.task->dictionaryAllocationPointer.integer & ( size - 1 ) ) \
50+ ALLERR; /* Steal the allocation error message. Need a new message. */ \
51+}
52+
53+
54+extern definition_header_s hHERE;
55+extern void HERE(void);
56+
4657 extern definition_header_s hALLOT;
4758 extern void ALLOT(void);
4859
--- trunk/bif6_a.h (revision 53)
+++ trunk/bif6_a.h (revision 54)
@@ -247,8 +247,9 @@
247247
248248 /*
249249 03600 TWID EQU 128 width of a terminal line
250+// 128 is too small on modern CPUs and OSses, but this is just prolonging the problem.
250251 */
251-#define TWID 128
252+#define TWID 512
252253
253254 /*
254255 03605 FCC 'QUERY'
旧リポジトリブラウザで表示